根据另一个查询集过滤查询集

时间:2018-08-24 13:33:37

标签: python django

我有一个名为UserCommunityProfiles的模型,其结构如下

class UserCommunityProfile(models.Model):
    owner = models.ForeignKey(
        User,
        on_delete = models.CASCADE)
    (...)

和称为订阅结构的模型:

class subscriptions(models.Model):
    subscriber = models.ForeignKey(
        User,
        on_delete = models.CASCADE, related_name='subscriber'
    )
    subscribed_to = models.ForeignKey(
        User,
        on_delete = models.CASCADE, related_name='subscribed_to'
    )

我要实现的目标是将不在查询集订阅中的每个用户的个人资料显示为subscribed_to,订阅者为request.user

我的观点是我所做的

subs = subscriptions.objects.filter(subscriber=request.user)
profiles = UserCommunityProfile.objects.exclude(owner=subs)

但是我收到一条错误消息,说Cannot use QuerySet for "subscriptions": Use a QuerySet for "User".,我该怎么办?

2 个答案:

答案 0 :(得分:4)

可以使用QuerySet来过滤其他QuerySet,但是正如这里的错误所述,您使用owner s,这意味着它希望与QuerySet包装了User,但是在这里您提供了一个包含QuerySet的{​​{1}}。

但是我们可以使用以下查询:

Subscriptions

此外,我们仍然不需要需要两个subs = User.objects.filter(subscribed_to__subscriber=request.user) profiles = UserCommunityProfile.objects.exclude(owner__in=subs),我们可以像这样查询它:

QuerySet

因此,这将提供一个profiles = UserCommunityProfile.objects.exclude( owner__subscribed_to__subscriber=request.user ),其中包含所有 QuerySet个,而{em> { 1}}是UserCommunityProfile,而Subscriptionsowner

如果您像上面演示的那样“组合”查询集,那么通常这将导致单个查询。这通常是更有效率的,因为所有的处理都在数据库级别完成,并且针对这些任务对数据库进行了优化。

在某些情况下,情况并非如此,例如,如果一个条件有两个分离条件,并且每个条件都产生一个(独立)subscribed_to个列表,那么最好使用subscriber重写查询。但这不是事实。

答案 1 :(得分:1)

解决方案:

subs=User.objects.filter(subscribed_to__subscriber=request.user).values_list('id')
profiles = UserCommunityProfile.objects.exclude(owner__in=subs)