[英]Django use LEFT JOIN instead of INNER JOIN
I have two models: Comments
and CommentFlags
我有两个模型:
Comments
和CommentFlags
class Comments(models.Model):
content_type = models.ForeignKey(ContentType,
verbose_name=_('content type'),
related_name="content_type_set_for_%(class)s",
on_delete=models.CASCADE)
object_pk = models.CharField(_('object ID'), db_index=True, max_length=64)
content_object = GenericForeignKey(ct_field="content_type", fk_field="object_pk")
submit_date = models.DateTimeField(_('date/time submitted'), default=None, db_index=True)
...
...
class CommentFlags(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="comment_flags",
on_delete=models.CASCADE)
comment = models.ForeignKey(Comment, related_name="flags", on_delete=models.CASCADE)
flag = models.CharField(max_length=30, db_index=True)
...
...
CommentFlags flag
can have values: like
, dislike
etc. CommentFlags
flag
可以有值: like
、 dislike
等。
Problem Statement : I want to get all Comments
sorted by number of likes in DESC manner.问题陈述:我想以DESC方式按喜欢的数量排序所有
Comments
。
Raw Query for above problem statement:上述问题陈述的原始查询:
SELECT
cmnts.*, coalesce(cmnt_flgs.num_like, 0) as num_like
FROM
comments cmnts
LEFT JOIN
(
SELECT
comment_id, Count(comment_id) AS num_like
FROM
comment_flags
WHERE
flag='like'
GROUP BY comment_id
) cmnt_flgs
ON
cmnt_flgs.comment_id = cmnts.id
ORDER BY
num_like DESC
I have not been able to convert the above query in Django ORM Queryset.我无法在 Django ORM 查询集中转换上述查询。
What I have tried so far...到目前为止我尝试过的...
>>> qs = (Comment.objects.filter(flags__flag='like').values('flags__comment_id')
.annotate(num_likes=Count('flags__comment_id')))
which generates different query.这会产生不同的查询。
>>> print(qs.query)
>>> SELECT "comment_flags"."comment_id",
COUNT("comment_flags"."comment_id") AS "num_likes"
FROM "comments"
INNER JOIN "comment_flags"
ON ("comments"."id" = "comment_flags"."comment_id")
WHERE "comment_flags"."flag" = 'like'
GROUP BY "comment_flags"."comment_id",
"comments"."submit_date"
ORDER BY "comments"."submit_date" ASC
LIMIT 21
Problem with above ORM queryset is, it uses InnerJoin and also I don't know how it adds submit_date in groupby clause.上述 ORM 查询集的问题是,它使用InnerJoin ,而且我不知道它如何在groupby子句中添加submit_date 。
Can you please suggest me a way to convert above mentioned Raw query to Django ORM queryset?您能否建议我将上述原始查询转换为 Django ORM 查询集的方法?
You can try using filter
argument in Count
:您可以尝试在
Count
中使用filter
参数:
qs = (Comment.objects.all()
.annotate(num_likes=Count('flags__comment_id', filter=Q(flags__flag='like'))))
It may produce slightly different query that you're expecting, depending on the database backend, but it should have equivalent behavior.根据数据库后端的不同,它可能会产生您所期望的略有不同的查询,但它应该具有相同的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.