tru*_*one 3 django django-aggregation
我正在尝试获取具有特定字段值的所有相关模型的计数。
这是一些代码...
模型.py:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
BAD = "BAD"
MEH = "MEH"
GOOD = "GOOD"
GREAT = "GREAT"
REVIEW_CHOICES = (
(BAD, BAD.title()),
(MEH, MEH.title()),
(GOOD, GOOD.title()),
(GREAT, GREAT.title()),
)
title = models.CharField(max_length=100)
review = models.CharField(max_length=100, choices=REVIEW_CHOICES)
author = models.ForeignKey(Author, related_name="books")
Run Code Online (Sandbox Code Playgroud)
假设我想列出每个作者的每种类型评论的数量。
我试过了:
Authors.object.annotate(n_good_books=Count("books")).filter(books__review="GOOD").values("name", "n_good_books")
Run Code Online (Sandbox Code Playgroud)
我也试过:
Authors.object.annotate(n_good_books=Count("books", filter=Q(books_review="GOOD"))).values("name", "n_good_books")
Run Code Online (Sandbox Code Playgroud)
但这些都不起作用。
有什么建议?
您需要.filter(..) 之前的.annotate(..),所以:
Authors.object.filter(
books__review="GOOD" # before the annotate
).annotate(
n_good_books=Count("books")
)Run Code Online (Sandbox Code Playgroud)
这将导致 a QuerySetof Authors,其中每个Author都有一个.n_good_books包含商品数量的额外属性Book。相反的意思是,您只会检索至少有一个相关人员获得好评的Authors 。如文档中所述:Book
当与使用
annotate()条款,过滤器具有的效果 限制针对其计算出的注释的对象。例如,您可以使用以下查询生成标题以“Django”开头的所有书籍的带注释的列表:Run Code Online (Sandbox Code Playgroud)>>> from django.db.models import Count, Avg >>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors'))(..)
也可以过滤带注释的值。注释的别名可以像任何其他模型字段一样用在
filter()andexclude()子句中。例如,要生成具有多个作者的书籍列表,您可以发出查询:
Run Code Online (Sandbox Code Playgroud)>>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1)此查询生成带注释的结果集,然后根据该注释生成过滤器。
该Count(..., filter=Q(..))方法只适用以来Django的2.0,所以在Django的1.11,这将无法工作。
| 归档时间: |
|
| 查看次数: |
2448 次 |
| 最近记录: |