How to query as GROUP BY in django?

前端 未结 9 1475
别跟我提以往
别跟我提以往 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 06:02

    The following module allows you to group Django models and still work with a QuerySet in the result: https://github.com/kako-nawao/django-group-by

    For example:

    from django_group_by import GroupByMixin
    
    class BookQuerySet(QuerySet, GroupByMixin):
        pass
    
    class Book(Model):
        title = TextField(...)
        author = ForeignKey(User, ...)
        shop = ForeignKey(Shop, ...)
        price = DecimalField(...)
    

    class GroupedBookListView(PaginationMixin, ListView):
        template_name = 'book/books.html'
        model = Book
        paginate_by = 100
    
        def get_queryset(self):
            return Book.objects.group_by('title', 'author').annotate(
                shop_count=Count('shop'), price_avg=Avg('price')).order_by(
                'name', 'author').distinct()
    
        def get_context_data(self, **kwargs):
            return super().get_context_data(total_count=self.get_queryset().count(), **kwargs)
    

    'book/books.html'

      {% for book in object_list %}
    • {{ book.title }}

      {{ book.author.last_name }}, {{ book.author.first_name }}

      {{ book.shop_count }}

      {{ book.price_avg }}

    • {% endfor %}

    The difference to the annotate/aggregate basic Django queries is the use of the attributes of a related field, e.g. book.author.last_name.

    If you need the PKs of the instances that have been grouped together, add the following annotation:

    .annotate(pks=ArrayAgg('id'))
    

    NOTE: ArrayAgg is a Postgres specific function, available from Django 1.9 onwards: https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/aggregates/#arrayagg

提交回复
热议问题