gpt4 book ai didi

python - 如何在基于外部查询的子查询中创建条件?

转载 作者:太空宇宙 更新时间:2023-11-04 04:59:15 25 4
gpt4 key购买 nike

我在 Airbnb 之类的应用程序上工作。我有一个 Flat 模型和一个 Price 模型,价格有不同类型的优先级,允许客户创建灵活的价格范围。

我坚持使用一个复杂的查询。此查询应按日期范围返回 Flats 并计算该范围的价格。


这是我模型的一部分:

class Flat(models.Model):
prices = models.ManyToManyField(
'Price'
related_name='flats'
)
price = models.PositiveIntegerField()
...

class Price(models.Model):
PRIORITY_CHOICES = ((i, i) for i in range(1, 6))

priority = PositiveIntegerField(choices=PRIORITY_CHOICES)
start_date = models.DateField()
end_date = models.DateField()
price = models.PositiveIntegerField()

到目前为止,我弄清楚了如何按每一天以更高的优先级注释价格。我为 Flat 写了一个自定义管理器:

class FlatManager(models.Manager):

def with_prices(self, start, end):
days = get_days(start, end) # utils function return list of days
prices = {}
for day in days:
prices[str(day)] = models.Subquery(
Price.objects.filter(
flats=models.OuterRef('pk')).
filter(start_date__lte=day, end_date__gte=day).
order_by('-priority').
values('price')[:1]
)
return self.annotate(**price_dict)

这是我的问题:

Flat 中的某些日期可以没有价格 block ​​,因此 Flat 有自己的 price 字段,以应对客户不想使用灵活价格的情况。我不知道我需要在查询中的什么地方添加条件运算符。如果我将它添加到 Price 子查询中,那么我将无法使用 Outref('price') 因为嵌套。当我解决它时,我认为计算聚合值的总和对我来说不会那么复杂。

请至少给出一些提示,我真的坚持了下来。

最佳答案

我将条件移动到主查询,检查子查询是否返回 None 然后使用 Flat 模型字段。
对于一个 date 值,它看起来像这样:

day = # some date
price = Price.objects.filter(
flats=models.OuterRef('pk')).
filter(start_date__lte=day, end_date__gte=day).
order_by('-priority').
values('price')[:1])
Flat.objects.annotate(price_block=Subquery(price).annotate(
derived_price = Case(
When(price_block__isnull=True, then='price'),
default=F('price_block')
))

因此 derived_price 值将包含来自 Price 模型的 price 值或来自 Flat 的 price 模型如果子查询返回 None
但就我而言,我有一个日期范围,所以我需要每个日期的子查询和条件。我还需要所有带注释价格的总和。
这是我的做法:

class FlatManager(models.Manager):

def _construct_conditions(self, keys):
# Function construct conditions
# like in previous example for each date in range
annotations = {}
for key in keys:
condition = {'{}__isnull'.format(key): True, 'then': 'price'}
annotations['derived_{}'.format(key)] = Case(When(**condition), default=F(key))
return annotations

def _add_prices(self, keys):
values = [F('derived_{}'.format(key)) for key in keys]
return sum(values)

def with_prices(self, start, end):
days = get_days(start, end) # utils function return list of days
prices = {}
for num, day in enumerate(days):
prices['price_{}'.format(num)] = Subquery(
Price.objects.filter(
flats=OuterRef('pk')).
filter(start_date__lte=day, end_date__gte=day).
order_by('-priority').
values('weekend_price' if day.weekday() in [4, 5] else 'price')[:1]
# also add a condition for weekend price
)
return (self.annotate(**prices).
annotate(**self._construct_conditions(prices.keys())).
annotate(sum=self._add_prices(prices.keys()))
)

关于python - 如何在基于外部查询的子查询中创建条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46239846/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com