Django 'exclude' 查询没有返回预期结果

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

我对 Django 比较陌生,这是我在论坛上的第一篇文章。

以下是应用程序中使用的模型(简化)。 该应用程序是关于在给定时间段内保留一组资源。

from django.db import models

class Resource(models.Model):
    id = models.AutoField(primary_key=True)
    serialno = models.CharField(max_length=30, null=False, unique=True)
    name = models.CharField(max_length=40, null=False)    

    def __str__(self):
        return f"{self.name}/{self.serialno}"

class Reservations(models.Model):

    id = models.AutoField(primary_key=True)
    active = models.BooleanField(default=True)
    name = models.CharField(max_length=30, null=False)
    startdate = models.DateField(null=False)
    enddate = models.DateField(null=False)    
    resource = models.ManyToManyField("myapp.Resource", db_table="myapp_resource_reservations", related_name="reservations")
    
    def __str__(self):
        return f"{self.name}/{self.startdate}/{self.enddate}"

例如,以下是模型中存在的数据

资源(格式:名称/序列号)

>>> Resource.objects.all()
  
<QuerySet [<Resource: Resource1/RES1>, <Resource: Resource2/RES2>, <Resource: Resource3/RES3>, <Resource: Resource4/RES4>]>
>>>

预订(格式:姓名/开始日期/结束日期/活动) Resource1

的所有预订
>>> Reservations.objects.all()
 
<QuerySet [<Reservations: Booking1/2023-03-01/2023-03-07/True>, <Reservations: Booking2/2023-03-15/2023-03-22/True>, <Reservations: BookingX/2023-03-08/2023-03-14/False>]>
>>>

我正在尝试使用以下查询检索在给定日期期间没有“活动”预订的所有资源。

>>> Resource.objects.exclude((Q(reservations__startdate__range=('2023-03-08','2023-03-14')) | Q(reservations__enddate__range=('2023-03-08','2023-03-14'))) & Q(reservations__active=True))
  
<QuerySet [<Resource: Resource2/RES2>, <Resource: Resource3/RES3>, <Resource: Resource4/RES4>]>
>>>

Resource1 确实有预订:2023-03-08 到 14 期间的 BookingX,但它是 active=False。我希望“Resource1”出现在上面的排除查询中,但它没有出现(预期逻辑:“排除日期范围内具有 active=True 保留的所有资源”)。

有人可以帮助理解为什么结果不如预期吗?我做错了什么?

尝试使用“过滤器”而不是“排除”,它的行为符合预期。

>>> Resource.objects.filter((Q(reservations__startdate__range=('2023-03-08','2023-03-14')) | Q(reservations__enddate__range=('2023-03-08','2023-03-14'))) & Q(reservations__active=True))
  
<QuerySet []>
>>>
>>> Resource.objects.filter((Q(reservations__startdate__range=('2023-03-08','2023-03-14')) | Q(reservations__enddate__range=('2023-03-08','2023-03-14'))) & Q(reservations__active=False)) 

<QuerySet [<Resource: Resource1/RES1>]>
>>>
django django-models django-orm
1个回答
0
投票

您基本上是在告诉 ORM 排除所有具有任何活动保留的资源。因为

&
首先被评估(在
|
之前)所以范围内的内容并不重要,因为它已经排除了 Resource 1 在这一点上。

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