اذهب إلى المحتوى

السؤال

نشر

لدي نموذج User ويمكنني أن أقوم بإرجاع كل المستخدمين من خلال الكود التالي:

User.objects.all()

ويقوم السطر السابق بإرجاع النتيجة التالية:

# Name, role, age
Amer, Admin, 22
Adam, user, 18
khaled, user, 23
Salah, Admin, 25

ما أريد القيام به هو تطبيق خاصية SQL وهي GROUB BY على الحقل role، كالتالي:

User.objects.all().group_by('role')

بالطبع الكود السابق لا يعمل. أعلم أنه يمكننا القيام ببعض بشيء مشابهة من خلال ملف django/db/Models/query.py ، لكني أريد أن أقوم بذلك بطريقة مباشرة مثل باقي الإستعلامات العادية.

Recommended Posts

  • 1
نشر

يمكنك أن تقوم بعمل تجميع aggregation من خلال التابع count كالتالي:

# يجب إستدعاؤ التابع أولًا
# في حالة تم إستدعاء models مسبقًا فيمكنك أن تستخدمه أيضًا
from django.db.models import Count

result = (User.objects
    .values('role')
    .annotate(dcount=Count('role')).order_by()
)

الكود السابق يقوم بتنفيذ جملة SQL التالية:

SELECT role, COUNT(role) AS dcount
FROM users GROUP BY role

وسوف تكون النتيجة كالتالي:

[{'role': 'Admin', 'dcount': 2}, 
 {'role': 'User', 'dcount': 2}]

إن أردت أن تحتوي النتيجة على أكثر من حقل، فيجب أن تقوم بإضافتهم إلى values كالتالي:

.values('role', 'name', 'age')

وهناك دائمًا حل آخر بديل وهو أن تقوم بتنفيذ جملة SQL فقط كالتالي:

result = User.objects.raw('''SELECT * FROM users GROUP BY role''')

لكن لا ينصح إستخدام هذا الحل، لأن جمل SQL المباشرة قد تؤدي إلى حدوث مشاكل أمنية وأخطاء غير متوقعه في كثير من الأحيان.

  • 0
نشر

إذا كنت تقصد القيام بتجميع البيانات فيمكنك استخدام ميزات التجميع الخاصة بـ ORM كالتالي

from django.db.models import Count
result = (User.objects
    .values('role')
    .annotate(dcount=Count('role'))
    .order_by()
)

ينتج عن هذا استعلام مشابه لـ

SELECT role, COUNT(role) AS dcount
FROM users GROUP BY role

 

  • 0
نشر (معدل)

كذلك يمكنك استخدام خاصية group_by :

query = Members.objects.all().query
query.group_by = ['role']
results = QuerySet(query=query, model=Members)

وحسب التوثيق، يمكنك أيضاً استخدام regroup للتجميع حسب السمات "attributes". أيضاً هذه الطريقة لا تعمل بالشكل الذي تتوقعه إذا لم تكن قائمة القواميس مرتبة بمفتاح، لذا قم بفرز قائمتك (أو ال query set الخاصة بك) حسب مفتاح grouper قبل تمريرها إلى regroup:

cities = [
    {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
    {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
    {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
    {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
    {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]
...
...
{% regroup cities by country as country_list %}
<ul>
    {% for country in country_list %}
        <li>{{ country.grouper }}
            <ul>
            {% for city in country.list %}
                <li>{{ city.name }}: {{ city.population }}</li>
            {% endfor %}
            </ul>
        </li>
    {% endfor %}
</ul>
"""
# الناتج سيكون كالتالي:
	..
    ..
    USA
        New York: 20,000,000
        Chicago: 7,000,000
    Japan
        Tokyo: 33,000,000

"""

 

تم التعديل في بواسطة Ali Haidar Ahmad

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...