我正在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()
表达式添加值?
注意:我的实际代码非常复杂,在不修改上述代码的整个结构的情况下获得答案真的很棒。
答案 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