Django Queryset针对两个排除条件和组合的排除条件返回不同的结果

问题描述 投票:1回答:1

为什么django对于以下两个exclude语句返回不同的结果?[Django排除语句1:

self.fields.exclude(record_type__isnull=True, field=None).prefetch_related('field', 'field__table')

相应的Django SQL查询:

SELECT field1, field2, field__table FROM `table` WHERE (`table`.`t_ct_id` = 2 AND `table`.`t_id` = 32 AND NOT (`table`.`record_type` IS NULL AND `table`.`field_id` IS NULL))

记录数:395

Django排除语句2:

self.fields.exclude(record_type__isnull=True).exclude(field=None).prefetch_related('field', 'field__table')

相应的Django SQL查询2:

SELECT field1, field2, field__table FROM `table` WHERE (`table`.`t_ct_id` = 2 AND `table`.`t_id` = 32 AND NOT (`table`.`incoming_record_type` IS NULL) AND NOT (`table`.`field_id` IS NULL))

记录数:152

我正在使用Django 2.2.11版和MYSQL作为数据库

mysql django django-models django-rest-framework
1个回答
0
投票

这很有意义,因为对于两个排除条件,这意味着您排除了第一和第二个元素。如果处于一种情况,则排除与两个combined。]相匹配的记录。

换句话说,在第一个查询集中,您说:

排除给定的record_typeNULL的记录

fieldNULL。但是,如果两个中的一个是NULL(另一个不是),则不要排除它。

在第二个查询集中,您说

排除record_typeNULL

]的元素> fieldNULL(或两者均为NULL)。

因此,在第二个查询中,您排除了更多元素,其中至少两个是NULL的元素。因此,如果您要计算其中两个元素之一为NULL的元素数,则将获得243条记录:

# will return 243 records where exactly one of the two fields is NULL

from django.db.models import Q

self.fields.filter(
    Q(record_type__isnull=False, field__isnull=True) |
    Q(record_type__isnull=True, field__isnull=False)
).count()  # 243

但是您可以在单个exclude语句中编写两个exclude的逻辑:

# 152 records

from django.db.models import Q

self.fields.exclude(
    Q(record_type=None) | Q(field=None)
).prefetch_related('field', 'field__table')

因此,我们从两个字段之一为NULL(或同时为两个字段)的那一刻起就排除了该记录。

© www.soinside.com 2019 - 2024. All rights reserved.