Django过滤器与排除
Posted
技术标签:
【中文标题】Django过滤器与排除【英文标题】:Django filter vs exclude 【发布时间】: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)
被认为是一种更好的做法还是它们在功能和性能上都相同?
【问题讨论】:
【参考方案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()
,但对于其他值,这可能会更加棘手。
【讨论】:
以上是关于Django过滤器与排除的主要内容,如果未能解决你的问题,请参考以下文章
Django REST Framework 中的否定或排除过滤器
使用跨越关系的字段查找在 django 模型上进行链式过滤和排除