我正在建立一个' airbnb克隆' Django上的应用程序。该应用程序具有灵活的价格体系。每个房东用户可以保存任意数量的价格,这些价格因优先级和日期范围而不同 以下是它的样子(为简单起见,大多数字段都被跳过):
class PriceBlock(models.Model):
price = models.DecimalField()
priority = models.CharField(choices=PRIORITY_CHOICES)
start_date = models.DateField()
end_date = models.DateField()
class Flat(models.Model):
prices = models.ManyToManyField(PriceBlock, related_name='flats')
例如,用户在一些随机月份中创建了3个PriceBlock
个实例,其中包含日期值
p1
- 优先级为1,价格为100美元,日期为1到3
p2
- 优先级为2,价格为200美元,日期为2到5年
p3
- 优先级为3,价格为300美元,日期为4到6
要计算本月1至6天的单位价格,我们需要计算每天优先级较高的PriceBlock的价格。
问题是 - 我需要在所有单位的ListView中计算每个单位的价格
以下是我的表现方式:
class FlatQueryset(models.QuerySet):
...
def with_block_full_price(self, start, end):
days = get_days(start, end) # function returns list of days nums
prices = {}
for num, day in enumerate(days):
prices[f'price_{num}'] = Subquery(
PriceBlock.objects.filter(flats=OuterRef('pk'))
.filter(start_date__lte=day, end_date__gte=day)
.order_by('-priority')
.values('price')[:1],
output_field=models.IntegerField(null=True))
return self.annotate(**prices).annotate(full_sum=sum([F(key) for key in prices.keys()]))
我在循环中创建子查询,每个子查询返回price
值,最优先考虑PriceBlock或null
,如果null
我不显示Flat
。然后,我将所有price
值添加到full_sum
值。
据我所知,我无法在原始SQL中执行此类查询,而无需重复每个日期的所有子查询。 我还有一个计算每个单位评级的任务,我也是这样做的 我很担心这样的任务可能有更好的解决方案,因为我的解决方案看起来很混乱。