对范围内的每一天执行子查询

时间:2017-11-17 15:29:44

标签: sql django django-queryset

我正在建立一个' 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个实例,其中包含日期值 enter image description here

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中执行此类查询,而无需重复每个日期的所有子查询。 我还有一个计算每个单位评级的任务,我也是这样做的 我很担心这样的任务可能有更好的解决方案,因为我的解决方案看起来很混乱。

0 个答案:

没有答案