对于Django> = 1.8
使用条件聚合:
from django.db.models import Count, Case, When, IntegerFieldArticle.objects.annotate( numviews=Count(Case( When(readership__what_time__lt=treshold, then=1), output_field=IntegerField(), )))
说明: 通过你的文章进行的常规查询将使用
numviews字段注释。该字段将被构造为CASE / WHEN表达式(由Count包裹),对于符合
NULL读者身份的条件和不符合条件的读者,将返回1 。计数将忽略空值,仅计数值。
对于近期未查看过的文章,你将得到零,并且可以使用该
numviews字段进行排序和过滤。
PostgreSQL的查询如下:
SELECt "app_article"."id", "app_article"."author", "app_article"."published", COUNT( CASE WHEN "app_readership"."what_time" < 2015-11-18 11:04:00.000000+01:00 THEN 1 ELSE NULL END ) as "numviews"FROM "app_article" LEFT OUTER JOIN "app_readership" ON ("app_article"."id" = "app_readership"."which_article_id")GROUP BY "app_article"."id", "app_article"."author", "app_article"."published"如果我们只想跟踪唯一查询,则可以在中添加区分
Count,并使
When子句返回值,我们想区分。
from django.db.models import Count, Case, When, CharField, FArticle.objects.annotate( numviews=Count(Case( When(readership__what_time__lt=treshold, then=F('readership__reader')), # it can be also `readership__reader_id`, it doesn't matter output_field=CharField(), ), distinct=True))这将产生:
SELECt "app_article"."id", "app_article"."author", "app_article"."published", COUNT( DISTINCT CASE WHEN "app_readership"."what_time" < 2015-11-18 11:04:00.000000+01:00 THEN "app_readership"."reader_id" ELSE NULL END ) as "numviews"FROM "app_article" LEFT OUTER JOIN "app_readership" ON ("app_article"."id" = "app_readership"."which_article_id")GROUP BY "app_article"."id", "app_article"."author", "app_article"."published"对于django <1.8和PostgreSQL你可以仅
raw用于执行由django的较新版本创建的SQL语句。显然,没有一种简单而优化的方法可以在不使用数据的情况下查询该数据
raw(即使
extra注入必填
JOIN子句存在一些问题)。
Articles.objects.raw('SELECt' ' "app_article"."id",' ' "app_article"."author",' ' "app_article"."published",' ' COUNT(' ' DISTINCT CASE WHEN "app_readership"."what_time" < 2015-11-18 11:04:00.000000+01:00 THEN "app_readership"."reader_id"' ' ELSE NULL END' ' ) as "numviews"' 'FROM "app_article" LEFT OUTER JOIN "app_readership"' ' ON ("app_article"."id" = "app_readership"."which_article_id")' 'GROUP BY "app_article"."id", "app_article"."author", "app_article"."published"')


