【问题标题】:Django filter vs excludeDjango过滤器与排除
【发布时间】:2011-01-26 05:09:06
【问题描述】:

django 中的 filter 和 exclude 有区别吗?如果我有

self.get_query_set().filter(modelField=x)

并且我想添加另一个条件,以下两行代码之间是否存在有意义的区别?

self.get_query_set().filter(user__isnull=False, modelField=x)

self.get_query_set().filter(modelField=x).exclude(user__isnull=True)

被认为是一种更好的做法还是它们在功能和性能上都相同?

【问题讨论】:

    标签: django django-queryset


    【解决方案1】:

    两者都被懒惰地评估,所以我希望它们表现相同。 SQL 可能不同,但没有真正的区别。

    【讨论】:

    • 谢谢。所以这只是个人喜好的问题吗?我只是想确保我不会做一些莫名其妙的愚蠢的事情。
    • @Enrico:不是真的,这取决于你想要什么。看我的回答。在这种情况下,性能并不重要,它们是用于不同目的的两种方法。对于 SQL 生成,文档中提到了 .exclude()多个参数在底层 SQL 语句中通过 AND 连接,整个内容包含在 NOT() 中。
    • @Felix。谢谢。我想我的主要问题 - 我本可以更清楚地传达的是关于 django 和最终 SQL 的性能。从您的后续评论中,听起来一个可能比另一个执行得更好,但主要基于生成的 SQL。但是,将第二个语句更改为 .exclude(user__isnull=True).filter(modelField=x) 将使这两个语句或多或少再次相等。
    【解决方案2】:

    通常排除与过滤相反。在这种情况下,两个示例的工作方式相同。

    这里:

    self.get_query_set().filter(user__isnull=False, modelField=x)
    

    您选择字段 user 不为 null 且 modelField 具有值 x 的条目

    在这种情况下:

    self.get_query_set().filter(modelField=x).exclude(user__isnull=True)
    

    首先选择 modelField 的值为 x 的条目(用户为 null 且用户不为 null),然后排除字段 user 为 null 的条目。

    我认为在这种情况下最好使用第一个选项,它看起来更干净。但两者的工作方式相同。

    【讨论】:

    • @angrysmit 你有这个声明的参考吗?
    【解决方案3】:

    这取决于您想要实现的目标。使用布尔值很容易在.exclude().filter() 之间切换,但是例如如果您想获取除 3 月的文章之外的所有文章?您可以将查询编写为

    Posts.objects.exclude(date__month=3)
    

    使用.filter() 会是(但我不确定这是否真的有效):

    Posts.objects.filter(date__month__in=[1,2,4,5,6,7,8,9,10,11,12])
    

    否则您将不得不使用Q 对象。

    正如函数名称所暗示的,.exclude() 用于从结果集中排除数据集。对于布尔值,您可以轻松地将其反转并改用.filter(),但对于其他值,这可能会更加棘手。

    【讨论】:

      猜你喜欢
      • 2011-11-13
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 2020-02-01
      • 1970-01-01
      • 2014-06-06
      • 2021-09-13
      • 1970-01-01
      相关资源
      最近更新 更多