我有一个带有starts_at、repeat_duration的预约模型
我想注释从生成的系列返回的重复值和持续时间字段直到结束日期
因此,如果预约日期为 14-07-2024,则 end_date 为 25-07-2024,持续时间为 3 天 它返回 14, 17, 20, 23 作为数组注释
但我得到的是同一个对象,返回多次,每次它都有系列结果的一个值
对于该示例,每个值将返回四次一,并且重复天数将是该值
object_1.repeat_days = 14 object_2.repeat_days = 17
如何让它只返回一个对象和数组形式的值
尝试用 arrayagg 来包装GenerateSeries,但我得到了
聚合函数调用不能包含设置返回函数调用
class AppointmentQuerySet(models.QuerySet):
def annotate_repeated_days(self, end_date):
return self.annotate(
repeat_dates=ArrayAgg(
GenerateSeries(
models.F("starts_at"), models.F("repeat_duration"), end_date
)
)
)
功能:
from django.db import models
class GenerateSeries(models.Func):
function = 'generate_series'
output_field = models.DateTimeField()
def __init__(self, start, step, stop, **extra):
expressions = [
start,
stop,
step
]
super().__init__(*expressions, **extra)
有什么想法吗?
这会导致错误指出的非法 SRF-in-aggregate 构造
array_agg(generate_series(starts_at,end_date,repeat_duration)) as repeat_dates
但是,通过将返回集合的函数移动到子查询中并让聚合函数从中提取行,可以很容易地避开限制:
(select array_agg(n) as repeat_dates
from generate_series(starts_at,end_date,repeat_duration) as g(n))
您可以通过设置
Func.subquery=True
: 让 Django 使用子查询语法
from django.db import models
class GenerateSeries(models.Func):
subquery = True ###################### here
function = 'generate_series'
output_field = models.DateTimeField()
def __init__(self, start, step, stop, **extra):
expressions = [#side-note: why reorder Postgres' (stOp,stEp) to (stEp,stOp)?
start,
stop,
step
]
super().__init__(*expressions, **extra)
# Decide if we need to use a subquery. # # Existing aggregations would cause incorrect results as # get_aggregation() must produce just one result and thus must not use # GROUP BY. # # If the query has limit or distinct, or uses set operations, then # those operations must be done in a subquery so that the query # aggregates on the limit and/or distinct results instead of applying # the distinct and limit after the aggregation.