【问题标题】:Django Query __isnull=True or = NoneDjango 查询 __isnull=True 或 = 无
【发布时间】:2015-07-03 17:16:23
【问题描述】:

这是一个简单的问题。我想知道写是不是一样:

queryset = Model.objects.filter(field=None)

比:

queryset = Model.objects.filter(field__isnull=True)

我正在使用 django 1.8

【问题讨论】:

    标签: django django-models django-queryset


    【解决方案1】:

    他们是平等的:

    >>> str(Person.objects.filter(age__isnull=True).query) == str(Person.objects.filter(age=None).query)
    True
    >>> print(Person.objects.filter(age=None).query)
    SELECT "person_person"."id", "person_person"."name", "person_person"."yes", "person_person"."age" FROM "person_person" WHERE "person_person"."age" IS NULL
    >>> print(Person.objects.filter(age__isnull=True).query)
    SELECT "person_person"."id", "person_person"."name", "person_person"."yes", "person_person"."age" FROM "person_person" WHERE "person_person"."age" IS NULL
    

    排除:Postgres JSON 字段(见@cameron-lee 的回答)

    【讨论】:

    • 只是想知道是否使用field__isnull=True' is not faster than field=None` 我想,isnull 会更快,因为它似乎与数据库匹配
    • @unlockme:好吧,它们会导致 same 查询:Django ORM 足够聪明,可以使用IS NULL,因此除了由于处理此@而导致的一些小差异987654325@,与__isnull=True翻译查询中的调用时,两者同时运行。
    • 我在使用 __in 和 None 时遇到了一些问题。例如: __in=(None, "", " ") 将导致 False,而 Q(__isnull=True)|Q(__in=("", " ")) 将导致 True。永远无法真正弄清楚原因。
    • @Dougyfresh 看起来像一个 Django 错误 - 这里也引用了:stackoverflow.com/questions/20225340/…
    • @Anupam,这不是错误。 Null 不会与包括 null 在内的任何值进行比较。例如,“选择 null = null;”将返回 null,而不是 true。 “在 [1, 2, null] 中选择 null”将返回 false。测试某事物是否为 null 的唯一方法是使用“is null”。
    【解决方案2】:

    这取决于字段的类型。正如其他答案中提到的,它们通常是等价的,但一般来说,这并不能保证。

    例如,Postgres JSON 字段使用=None 指定json 的值为null__isnull=True 表示没有json:

    https://docs.djangoproject.com/en/3.0/ref/contrib/postgres/fields/#jsonfield

    【讨论】:

    • 非常好的答案!喜欢它
    • 我目前很难匹配“无”Postgres JSON 字段。 filter(field__is_null=True) 或 filter(field=None) 都不起作用。我将如何匹配这些 null postgres JSON 字段?
    • @thrillhouse:听起来你可能已经存储了字符串“None”,它不同于 SQL null 或 json null。
    【解决方案3】:

    请记住,您无法使用第一个解决方案来逆转条件:

    # YOU CANNOT DO THIS
    queryset = Model.objects.filter(field!=None)
    

    但是你可以这样做:

    queryset = Model.objects.filter(field__isnull=False)
    

    【讨论】:

    • 如果您需要反转条件,您可以使用.exclude(field=None) - 我个人更喜欢.exclude,因为它更明确。
    • 但是,每次执行此操作时,您都会包装查询,并且如果不必要的话,多个查询包装可能会很麻烦,甚至会降低性能@PauloScardine
    • 有趣,@wonderwhy 为什么你有由于包装导致的“性能下降”的来源?由于多重包装,我在使用 PostgreSQL 时从来没有出现过任何性能故障——根据我的经验,规划器在这种查询方面做得非常好。关于查询是繁琐的 SQL 方式,使用 ORM 的全部意义在于不必处理 SQL - 只要它执行良好,我就不会关心自动生成的 SQL... :-)
    • 相当评论
    猜你喜欢
    • 2021-05-01
    • 2013-04-27
    • 2012-12-31
    • 2017-07-22
    • 2017-10-22
    • 2018-05-15
    • 2015-04-08
    • 2018-01-21
    • 1970-01-01
    相关资源
    最近更新 更多