是否可以对OuterRef表达式进行算术运算?

时间:2018-01-12 16:58:17

标签: python django django-models orm

我正在django建立一个体验预订系统,我有以下模型。

class Experience(models.Model):
 name = models.CharField(max_length=20)
 capacity = models.IntegerField()

class Booking(models.Model):
 experience = models.ForeignKey(Experience)
 occupied = models.IntegerField()

每种体验的容量都有限,当用户进行预订时,它将被添加到具有占用号码的预订表中。现在我将如何找到未完全占用的经验?

available_experiences = Experience.objects.all().exclude(id__in=Subquery(Booking.objects.filter(occupied__gt=OuterRef('capacity') - request_persons).values_list('experience', flat=True)))

此处,request_persons是体验中所需空缺的数量。这不起作用,并显示'ResolvedOuterRef' object has no attribute 'relabeled_clone'之类的错误。是否可以对OutRef()这样的F()表达式进行算术运算?

不添加request_persons,上述代码有效。为什么无法为OutRef()表达式添加值?

注意:我的实际代码非常复杂,在不修改上述代码的整个结构的情况下获得答案真的很棒。

2 个答案:

答案 0 :(得分:1)

通过直接在OuterRef()引用的查询中执行算术运算,您可以解决此问题:

available_experiences = Experience.objects.annotate(
    total=models.F('capacity') - request_persons
).exclude(
    id__in=Subquery(Booking.objects.filter(
        occupied__gt=OuterRef('total')
    ).values_list('experience', flat=True))
)

如果您在未修改结构或使用RawSQL().extra()的情况下找到了另一种方式,请告诉我们!

答案 1 :(得分:1)

这似乎在Django 2.0中已解决:https://github.com/django/django/pull/9722/files

可以通过类似的方式将修复程序反向移植到1.11.x:

from django.db.models.expressions import ResolvedOuterRef
if not hasattr(ResolvedOuterRef, 'relabeled_clone'):
    ResolvedOuterRef.relabeled_clone = lambda self, relabels: self