首页 > 解决方案 > Django intersect count annotate 用于排序

问题描述

在这个问题中,我们得到了一个解决方案,可以根据两个多对多字段的交集对查询进行排序。虽然这是一个很好的答案,但限制是您必须先过滤。

假设我有相同的两个模型。有没有办法通过交叉点数来注释所有结果,这样我就可以显示所有问题,而不管位置如何,但仍然按位置排序?

class Location(models.Model):
    name = models.CharField(max_length=100)


class Profile(models.Model):
    locations_of_interest = models.ManyToManyField(Location)


class Question(models.Model):
    locations = models.ManyToManyField(Location)

我希望我能做这样的事情:

from django.db.models import Count

matching_profiles = Profile.objects.all().annotate(
    locnom=Count('locations_of_interest__in=question.locations.all()')
)

有任何想法吗?我只需要进行两个查询并将它们合并吗?

标签: pythonsqldjangodjango-modelsdjango-queryset

解决方案


我们也可以在Count函数中移动过滤:

Profile.objects.annotate(
    locnom=Count('id', filter=Q(locations_of_interest__in=question.locations.all()))
)

在没有相关s 的s的意义上,这两者是等价的,或者在没有位置的情况下仍将包括在内,在这种情况下,那将是。ProfileLocationquestion.locnomProfile0

查询大致如下:

SELECT profile.*,
       COUNT(CASE WHEN proloc.location_id IN (1, 4, 5) THEN profile.id ELSE NULL)
           AS locnom
FROM profile
LEFT OUTER JOIN profile_locations_of_interest AS proloc
             ON profile.id = proloc.profile_id
GROUP BY profile.id

的相关s 的[1, 4, 5]样本 哪里?idLocationquestion


推荐阅读