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

时间:2009-05-10 02:26:50

标签: django django-models django-queryset filter null

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

只有我能做到:

Name.objects.filter(alias!="")

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

8 个答案:

答案 0 :(得分:760)

你可以这样做:

Name.objects.exclude(alias__isnull=True)

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

Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')

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

alias

您还可以将多个参数传递给SELECT * FROM Name WHERE alias IS NOT NULL AND alias != "" 的单个调用,这样可以确保只排除符合每个条件的对象:

exclude

此处,Name.objects.exclude(some_field=True, other_field=True) some_field为真的行被排除在外,因此我们得到两个字段都不为真的所有行。生成的SQL代码看起来有点像这样:

other_field

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

SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)

有关详细信息,请参阅Django文档中的this pagethis page

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

答案 1 :(得分:36)

Name.objects.filter(alias__gt='',alias__isnull=False)

答案 2 :(得分:35)

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

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

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

Name.objects.exclude(alias__isnull=True).exclude(alias="")

这应该可以为您提供所需的设置。

答案 3 :(得分:4)

来自Django 1.8,

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)

答案 4 :(得分:0)

你可以这样做:

Name.objects.exclude(alias="").exclude(alias=None)

真的很简单。 filter用于匹配,exclude用于匹配除指定内容之外的所有内容。这会将SQL评估为NOT alias='' AND alias IS NOT NULL

答案 5 :(得分:0)

这是另一种简单的方法。

Name.objects.exclude(alias=None)

答案 6 :(得分:0)

为避免在使用exclude时遇到常见错误,请记住:

您可以多个条件添加到 exclude()块中,例如filter。 要排除多个条件,必须使用多个exclude()

示例

  

不正确

     

User.objects.filter(email='example@example.com')。exclude(profile__nick_name ='',   profile__avt ='')

     

正确

     

User.objects.filter(email='example@example.com')。exclude(profile__nick_name ='')。exclude(profile__avt ='')

答案 7 :(得分:0)

另一种使用通用 isempty 查找的方法,可用于任何字段。

它也可以被 django rest_framework 或其他使用 django 查找的应用程序使用:

from distutils.util import strtobool
from django.db.models import Field
from django.db.models.lookups import BuiltinLookup

@Field.register_lookup
class IsEmpty(BuiltinLookup):
    lookup_name = 'isempty'
    prepare_rhs = False

    def as_sql(self, compiler, connection):
        sql, params = compiler.compile(self.lhs)
        condition = self.rhs if isinstance(self.rhs, bool) else bool(strtobool(self.rhs))
        if condition:
            return "%s IS NULL or %s = ''" % (sql, sql), params
        else:
            return "%s <> ''" % sql, params

然后你可以像这样使用它:

Name.objects.filter(alias__isempty=False)