过滤查询集中的空名称或NULL名称

un3*_*33k 444 django null filter django-models django-queryset

我有first_name,last_name和别名(可选)我需要搜索.所以,我需要一个查询来给我所有具有别名集的名称.

只有我能做到:

Name.objects.filter(alias!="")
Run Code Online (Sandbox Code Playgroud)

那么,与上述相同的是什么?

Sas*_*gov 809

你可以这样做:

Name.objects.exclude(alias__isnull=True)
Run Code Online (Sandbox Code Playgroud)

如果您需要排除空值空字符串,那么首选方法是将条件链接在一起,如下所示:

Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')
Run Code Online (Sandbox Code Playgroud)

将这些方法链接在一起基本上可以独立地检查每个条件:在上面的示例中,我们排除其中alias为null 空字符串的行,因此您将获得Name具有非null,非空alias字段的所有对象.生成的SQL看起来像:

SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""
Run Code Online (Sandbox Code Playgroud)

您还可以将多个参数传递给单个调用exclude,这将确保只排除满足每个条件的对象:

Name.objects.exclude(some_field=True, other_field=True)
Run Code Online (Sandbox Code Playgroud)

在这里,排除了哪些some_field 哪些other_field是真的行,所以我们得到两个字段都不为真的所有行.生成的SQL代码看起来有点像这样:

SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)
Run Code Online (Sandbox Code Playgroud)

或者,如果您的逻辑比这更复杂,您可以使用Django的Q对象:

from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅Django文档中的此页面此页面.

暂且不说:我的SQL示例只是一个类比 - 实际生成的SQL代码可能看起来不同.通过实际查看它们生成的SQL,您将更深入地了解Django查询的工作方式.

  • 我认为你的编辑是错误的:链接过滤器不会自动创建一个SQL"OR"(仅在这种情况下),它会产生一个SQL`AND`.请参阅此页面以供参考:https://docs.djangoproject.com/en/dev/topics/db/queries/#chaining-filters链接的优点是可以混合使用`exclude`和`filter`来模拟复杂的查询条件.如果你想建立一个真正的SQL`OD`你必须使用Django Q对象:https://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects请编辑你的编辑以反映这一点,因为答案是严重误导的. (5认同)
  • 我知道De Morgan的定律,这完全是我的观点:你的例子只是有效,因为它有利于将第一个查询中的`AND`转换为`OR`,因为你正在使用`exclude`.在一般情况下,将链接视为"THEN"可能更为正确,即"排除(A)然后排除(B)".对于上面的严厉语言感到抱歉.你的答案确实很好,但我担心新开发人员会过于普遍地回答你的问题. (3认同)
  • @shezi:够公平的.我同意以Django术语而不是SQL术语来思考它更好,我只是认为用"AND"和"OR"来表示链接对于从SQL背景来到Django的人来说可能是有用的.为了更深入地了解Django,我认为文档比我做得更好. (2认同)

小智 42

Name.objects.filter(alias__gt='',alias__isnull=False)
Run Code Online (Sandbox Code Playgroud)

  • 我不确定,但是我认为`alias__isnull = False`条件是多余的。如果字段为Null,那么肯定会被第一个子句排除吗? (2认同)

b3n*_*ng0 37

首先,Django文档强烈建议不要对基于字符串的字段(如CharField或TextField)使用NULL值.阅读文档以获得解释:

https://docs.djangoproject.com/en/dev/ref/models/fields/#null

解决方案:我认为你也可以在QuerySets上链接方法.试试这个:

Name.objects.exclude(alias__isnull=True).exclude(alias="")
Run Code Online (Sandbox Code Playgroud)

这应该给你你正在寻找的集合.


Afs*_*ati 9

如果要排除 null ( None)、空字符串 ( "") 以及包含空格 ( " ") 的字符串,可以使用__regexwith with__isnull过滤选项

Name.objects.filter(
    alias__isnull = False, 
    alias__regex = r"\S+"
)
Run Code Online (Sandbox Code Playgroud)

alias__isnull=False排除所有列空列

aliax__regex = r"\S+"确保列值至少包含一个或多个非空白字符。


Che*_*mer 5

从Django 1.8开始,

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是“您可以*做的事情”,而不是您*应*做的事情。它通过两个简单的检查大大提高了查询的复杂性。 (4认同)

Hoa*_*ell 5

1. 使用 exclude 时,请记住以下几点以避免常见错误:

如果添加多个条件成一个 exclude()像块filter()。要排除多个条件,您应该使用多个 exclude().

例子: (NOT a AND NOT b)

Entry.objects.exclude(title='').exclude(headline='')
Run Code Online (Sandbox Code Playgroud)

等于

SELECT... WHERE NOT title = '' AND NOT headline = ''
Run Code Online (Sandbox Code Playgroud)

================================================== ====

2. 只有在你真正了解它时才使用多个:

例子: NOT (a AND b)

Entry.objects.exclude(title='', headline='')
Run Code Online (Sandbox Code Playgroud)

等于

SELECT.. WHERE NOT (title = '' AND headline = '')
Run Code Online (Sandbox Code Playgroud)

  • [文档](https://docs.djangoproject.com/en/stable/ref/models/querysets/#exclude)非常清楚,您可以在`.exclude()`中包含多个条件,但它们的工作方式不同然后分开。这与“NOT (a AND b)”和“(NOT a AND NOT b)”之间的区别相同。 (2认同)