【问题标题】:Django intersect count annotate for sortingDjango intersect count annotate 用于排序
【发布时间】:2019-01-01 10:20:41
【问题描述】:

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

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

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()')
)

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

【问题讨论】:

    标签: python sql django django-models django-queryset


    【解决方案1】:

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

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

    两者等效,因为Profiles 与no 相关Locations,或者如果question 没有位置,将仍然包括在内,在这种情况下,Profile.locnom 将是0

    查询大致如下:

    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
    

    [1, 4, 5] 在这里示例ids 的相关Locations 的question

    【讨论】:

      【解决方案2】:

      尝试使用子查询https://docs.djangoproject.com/fr/2.0/ref/models/expressions/#subquery-expressions

      比如这个例子:https://books.agiliq.com/projects/django-orm-cookbook/en/latest/subquery.html

      from django.db.models import Subquery
      users = User.objects.all()
      UserParent.objects.filter(user_id__in=Subquery(users.values('id')))
      

      【讨论】:

        猜你喜欢
        • 2021-11-28
        • 1970-01-01
        • 2016-05-11
        • 2017-10-02
        • 2021-04-24
        • 1970-01-01
        • 2012-06-13
        • 1970-01-01
        • 2011-05-02
        相关资源
        最近更新 更多