Django 'exclude'查询未返回预期结果

pgky5nke  于 2023-02-25  发布在  Go
关注(0)|答案(1)|浏览(119)

我对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>]>
>>>

预订(格式:name/startdate/enddate/active)为资源1进行所有保留

>>> 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>]>
>>>

资源1具有保留:2023年3月8日至14日期间的BookingX,但它处于活动状态=False。我希望“Resource 1”显示在上述排除查询中,但它没有显示(预期逻辑:'排除日期范围内具有活动=真保留的所有资源')。
有没有人能帮助理解为什么结果不像预期的那样?我做错了什么?
尝试使用“filter”而不是“exclude”,其行为符合预期。

>>> 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>]>
>>>
vohkndzv

vohkndzv1#

您基本上是告诉ORM排除所有具有ANY活动预留的资源。因为首先评估&(在|之前),所以范围内的内容实际上并不重要,因为它已经在该点排除了资源1。

相关问题