将范围的一部分注释到新字段

时间:2018-06-26 14:10:03

标签: django django-postgresql

因此,我们一直在预订模型中使用DateTimeRangeField来表示开始和结束。这样做的理由可能不是很好-事后看来,单独的开始和结束字段可能会更好-但是我们现在已经过去了一年多,没有回头路了。

通常情况很好,只是我需要将结束日期时间注释到相关模型的查询上。而且我无法确定语法。

这是一个小玩具示例,我想要一个列出最后一次预订结束的员工列表。

class Booking(models.Model):
    timeframe = DateTimeRangeField()
    employee = models.ForeignKey('Employee')

sq = Booking.objects.filter(employee=OuterRef('pk')).values('timeframe')
Employee.objects.annotate(last_on_site=Subquery(sq, output_field=DateTimeField()))

那是行不通的,因为带注释的值是范围,而不是单个值。我已经尝试了很多修饰符(例如__1 .1,但没有用)。

有没有办法只获得一个值?我猜您可以进行此操作而无需子查询的复杂性,而只需执行简单的值查找即可。 Booking.objects.values('timeframe__start')(或其他)。从本质上讲,这就是我要在这里做的。

1 个答案:

答案 0 :(得分:0)

感谢IRC中的一些帮助,事实证明您可以直接使用RangeStartsWith和RangeEndsWith模型转换类。这些通常是为了向您提供对范围值的__startswith过滤器访问而注册的,但是它们可以直接拉回该值。

在我的示例中,这意味着只需稍微修改批注:

from django.contrib.postgres.fields.ranges import RangeEndsWith
sq = Booking.objects.filter(employee=OuterRef('pk')).values('timeframe')
Employee.objects.annotate(last_on_site=RangeEndsWith(Subquery(sq[:1])))