【问题标题】:Django queries merged with "|" return duplicatesDjango 查询与“|”合并返回重复项
【发布时间】:2015-11-15 14:50:41
【问题描述】:

我有一个Channel 模型。

在我看来,我有以下几行:

def default_channels(request) :     return Channel.objects.filter(is_default=True)
def subbed_channels(request):       return Channel.objects.filter(subscribers=request.user)
def moderated_channels(request):    return Channel.objects.filter(moderators=request.user)

然后

channels = default_channels(request) | subbed_channels(request) | moderated_channels(request)

通常,如果我理解正确,这应该返回所有默认的、我订阅的或我主持的频道。但是,如果一个通道存在于多个过滤器中,则不应多次返回它。

但是,出于某种原因,channels 对象多次返回某些对象。我什至有一个返回 4 次的频道!

我该如何调试和解决这个问题?我是否使用“|”算错了?

【问题讨论】:

  • queryset 有一个 .distinct() 方法,可用于删除重复查询:docs.djangoproject.com/en/dev/ref/models/querysets/#values 但是,请查看模型管理器。此外,所有这些视图都可以合并为一个。
  • 感谢@user2707389,distinct() 似乎是最合乎逻辑的解决方法。我还有其他几个视图结合了我的频道的不同变体,这就是我这样构建它的原因。您想发布您的distinct() 解决方案以便我将其标记为最佳吗?
  • 发布了我的解决方案。随意将其标记为正确。谢谢。

标签: django django-queryset


【解决方案1】:

queryset 有一个.distinct() 方法,可用于删除重复查询。

阅读文档here

但是,请查看模型管理器。所有这些视图都可以合并为一个。

【讨论】:

    【解决方案2】:
    channels = default_channels(request) | subbed_channels(request) | moderated_channels(request)
    
    channels = channels.distinct()
    

    【讨论】:

      【解决方案3】:

      使用Q objects 更好地完成您想要的。在你的情况下:

      from django.db.models import Q
      
      channels = Channel.objects.filter(Q(is_default=True) | Q(subscribers=request.user) | Q(moderators=request.user))
      

      应该做的工作。

      【讨论】:

      • 您好@Sirion,感谢您的回复。为什么使用 Q 更好?
      • Q 对象是专门为这个用例制作的,最好使用 | 进行记录(我认为这是 django 内部功能,因此不可靠)。此外,我的方法只会生成 1 个查询,这比 3 个查询要好(即使我不完全确定使用您的方法实际上会有 3 个查询或只有一个)。
      猜你喜欢
      • 2016-05-08
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 2011-08-20
      相关资源
      最近更新 更多