How to query as GROUP BY in django?

前端 未结 9 1253
别跟我提以往
别跟我提以往 2020-11-22 05:40

I query a model:

Members.objects.all()

And it returns:

Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2         


        
相关标签:
9条回答
  • 2020-11-22 05:48

    If I'm not mistaking you can use, whatever-query-set.group_by=['field']

    0 讨论(0)
  • 2020-11-22 05:51

    You need to do custom SQL as exemplified in this snippet:

    Custom SQL via subquery

    Or in a custom manager as shown in the online Django docs:

    Adding extra Manager methods

    0 讨论(0)
  • 2020-11-22 05:54

    You can also use the regroup template tag to group by attributes. From the docs:

    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>
    

    Looks like this:

    • India
      • Mumbai: 19,000,000
      • Calcutta: 15,000,000
    • USA
      • New York: 20,000,000
      • Chicago: 7,000,000
    • Japan
      • Tokyo: 33,000,000

    It also works on QuerySets I believe.

    source: https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#regroup

    edit: note the regroup tag does not work as you would expect it to if your list of dictionaries is not key-sorted. It works iteratively. So sort your list (or query set) by the key of the grouper before passing it to the regroup tag.

    0 讨论(0)
  • 2020-11-22 05:54
    from django.db.models import Sum
    Members.objects.annotate(total=Sum(designation))
    

    first you need to import Sum then ..

    0 讨论(0)
  • 2020-11-22 05:57

    An easy solution, but not the proper way is to use raw SQL:

    results = Members.objects.raw('SELECT * FROM myapp_members GROUP BY designation')
    

    Another solution is to use the group_by property:

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

    You can now iterate over the results variable to retrieve your results. Note that group_by is not documented and may be changed in future version of Django.

    And... why do you want to use group_by? If you don't use aggregation, you can use order_by to achieve an alike result.

    0 讨论(0)
  • 2020-11-22 05:59

    Django does not support free group by queries. I learned it in the very bad way. ORM is not designed to support stuff like what you want to do, without using custom SQL. You are limited to:

    • RAW sql (i.e. MyModel.objects.raw())
    • cr.execute sentences (and a hand-made parsing of the result).
    • .annotate() (the group by sentences are performed in the child model for .annotate(), in examples like aggregating lines_count=Count('lines'))).

    Over a queryset qs you can call qs.query.group_by = ['field1', 'field2', ...] but it is risky if you don't know what query are you editing and have no guarantee that it will work and not break internals of the QuerySet object. Besides, it is an internal (undocumented) API you should not access directly without risking the code not being anymore compatible with future Django versions.

    0 讨论(0)
提交回复
热议问题