540

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

只要我能做到:

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

那么,与上面的等价物是什么?

4

8 回答 8

977

你可以这样做:

Name.objects.exclude(alias__isnull=True)

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

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

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

SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""

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

Name.objects.exclude(some_field=True, other_field=True)

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

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

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

from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))

有关更多信息,请参阅此页面和Django 文档中的此页面。

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

于 2009-05-10T02:41:37.250 回答
63
Name.objects.filter(alias__gt='',alias__isnull=False)
于 2011-02-23T09:14:06.693 回答
41

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

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

解决方案:我认为,您也可以将 QuerySets 上的方法链接在一起。试试这个:

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

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

于 2009-06-04T15:15:18.940 回答
5

从 Django 1.8 开始,

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)
于 2016-03-06T12:02:21.147 回答
5

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

不应多个条件添加 exclude()filter(). 要排除多个条件,您应该使用多个 exclude().

例子:(NOT a AND NOT b)

Entry.objects.exclude(title='').exclude(headline='')

等于

SELECT... WHERE NOT title = '' AND NOT headline = ''

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

2.只有在你真正了解它的时候才使用multiple:

例子:NOT (a AND b)

Entry.objects.exclude(title='', headline='')

等于

SELECT.. WHERE NOT (title = '' AND headline = '')
于 2019-07-04T10:50:41.310 回答
1

你可以简单地这样做:

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

真的就是这么简单。 filter用于匹配并且exclude是匹配除指定内容之外的所有内容。这将评估为 SQL 为NOT alias='' AND alias IS NOT NULL.

于 2018-05-08T15:29:35.357 回答
0

这是另一种简单的方法。

Name.objects.exclude(alias=None)
于 2018-10-10T17:15:44.327 回答
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)
于 2021-05-29T12:37:26.937 回答