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

只要我能做到:

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

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


当前回答

你可以简单地这样做:

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

其实就是这么简单。Filter用于匹配,exclude用于匹配除指定内容以外的所有内容。这将在SQL中计算为NOT alias= " AND alias IS NOT NULL。

其他回答

如果你想排除null (None),空字符串(""),以及包含空格的字符串(""),你可以使用__regex和__isnull过滤器选项

Name.objects.filter(
    alias__isnull = False, 
    alias__regex = r"\S+"
)

alias__isnull=False排除所有空列

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

另一种方法是使用泛型的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)

从Django 1.8,

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)
Name.objects.filter(alias__gt='',alias__isnull=False)

1. 在使用exclude时,请记住以下内容,以避免常见错误:

不应该像filter()那样在exclude()块中添加多个条件。要排除多个条件,应该使用multiple exclude()。

例子:(不是a也不是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 = '')