具有跨不同模型注释的复杂查询集



我使用的是Django 1.6,并有以下模型(为了可读性而简化了一点):

class Person(models.Model):
    name = models.CharField(max_length=128)
class Room(models.Model):
    max_persons = models.SmallIntegerField()
    name = models.CharField(max_length=30, unique=True)
class Stay(models.Model):
    person = models.ForeignKey(Person)
    STAY_TYPE = (
        (1, 'Type 1'),
        (2, 'Type 2'),
        (3, 'Type 3'),
    )
    stay_type = models.CharField(max_length=1, choices=STAY_TYPE)
class Hospitalization(models.Model):
    stay = models.ForeignKey(Stay)
    date_in = models.DateField()
    date_out = models.DateField(blank=True, null=True)
    room = models.ForeignKey(Room)

有了queryset(在经理中),我想获得给定日期的所有可用房间,即不满足max_persons的房间。

到目前为止,我已经尝试过使用Q和类似Room.objects.filter(hospitalization__date_out__lt="2014-04-25")的东西,但我无法计算出max_persons的比较。

你知道吗?

编辑

与每个房间相关的Person对象数代表该房间中的人数。

因此,根据卡尔下面的建议,我试着玩一下:

  • Room.objects.filter(hospitalization__date_out__lte="2014-04-25").annotate(num_persons=hospitalization_set__stay__person.Count()).exclude(num_persons__lte=max_persons)
    • 产生NameError: name 'hospitalization_set__stay__person' is not defined
  • Room.objects.filter(hospitalization__date_out__lte="2014-04-25").annotate(num_persons=Count('hospitalization_set__stay__person')).exclude(num_persons__lte=max_persons)
    • 产生FieldError: Cannot resolve keyword 'hospitalization_set' into field.
  • Room.objects.filter(hospitalization__date_out__lte="2014-04-25").annotate(num_persons=Count('hospitalization__stay__person')).exclude(num_persons__lte=F('max_persons'))
    • 不产生任何结果([]),而根据我当前的DB,我预计至少会有三个结果
    • 删除.exclude()时,我仍然没有得到任何结果。看起来我正在使用的.annotate()出现了问题

我相信类似于Room.objects.filter(hospitalization__date_out="2014-04-25", max_persons__lt=x)的东西应该能起到作用。请记住,在一个筛选器操作中可以有多个声明,还可以链接排除和筛选器。这不会增加数据库活动;仅当对CCD_ 16本身进行评估时才执行CCD_。请参阅Django文档中的查询。

编辑:事实证明,这比我最初想象的稍微复杂一些,但我相信我已经解决了(在导入您的模型声明并进行shell会话之后!)

rooms = Room.objects.filter(DATE FILTERING HERE).annotate(num_persons=Count('hospitalization__room__id')).filter(num_persons__lt=F('max_persons')).count()

将为您提供num_persons(我们上面注释的变量)小于max_persons的房间数量,并提前进行日期筛选。

请记住包括所需的导入:from django.db.models import Countfrom django.db.models import F

相关内容

  • 没有找到相关文章

最新更新