【问题标题】:Django Query with conditional function When (?)带有条件函数When(?)的Django Query
【发布时间】:2017-07-09 11:22:57
【问题描述】:

我有一个餐厅的数据库:

class Product(models.Model):
    name = models.CharField(max_length=250)
    sides = models.ManyToManyField(Sides, blank=True)
    price = models.DecimalField(max_digits=5, decimal_places=2)

    def __unicode__(self):
        return '%s %s %s' % (self.name, self.sides, self.price)

    def __repr__(self):
        return unicode(self).encode('utf-8')


class Menu(models.Model):
    date = models.DateField()
    product = models.ForeignKey(Product)

    def __unicode__(self):
        return '%s %s' % (self.date, self.product)

    def __repr__(self):
        return unicode(self).encode('utf-8')


class Order(models.Model):
    date = models.DateField()
    user = models.ForeignKey(User, null=True)

    def __unicode__(self):
        return '%s %s' % (self.date, self.user)

    def __repr__(self):
        return unicode(self).encode('utf-8')


class OrderItems(models.Model):
    order = models.ForeignKey(Order)
    product = models.ForeignKey(Menu, null=True, blank=True)
    quantity = models.IntegerField(default=0)
    take_away = models.BooleanField(default=False)

    def __unicode__(self):
        return '%s %s %s %s' % (self.order, self.product, self.quantity, self.take_away)

    def __repr__(self):
        return unicode(self).encode('utf-8')

我需要在数据库中搜索我的用户在给定时间段内点菜的费用,所以第一个查询很简单:

report = OrderItems.objects.filter(Q(order__date__range=(strfrom, strto)), ~Q(order__user_id=None))

问题开始于计算此期间每位用户的总成本,因为我必须为每个已标记为外卖的项目加 1(布尔字段)。到目前为止,我的查询忽略了布尔字段,就像这样:

per_person = report.values('order__user').annotate(per_capita=Sum(F('quantity')*(F('product__product__price')), output_field=DecimalField()))

我的问题是:如何将布尔字段标记为 True 的每个商品价格加 1?我假设我必须使用条件函数'When'。

我尝试了类似的方法:

report.values('order__user').annotate(per_capita=Sum(F('quantity')*(F(When('take_away'==True, then='product__product__price')+1)|(When('take_away'==False, then='product__product__price'))), output_field=DecimalField()))

但是,很明显,它给出了一个错误__init__() takes either a Q object or lookups as keyword arguments

【问题讨论】:

    标签: python django postgresql django-queryset


    【解决方案1】:

    您可以使用 Case-When。查看https://docs.djangoproject.com/en/1.10/ref/models/conditional-expressions/#case中的示例

    .annotate(per_capita=Sum(
        F('quantity') * (F('product__product__price') +
        Case(When(take_away=True, then=Value(1)),
             default_case=Value(0),
             output_field=DecimalField())
        )
    ))
    

    【讨论】:

    • 做到了。谢谢!
    • 我很高兴它有帮助。如果您喜欢,请不要忘记为答案投票=)
    • 有什么方法可以检查方程F('quantity') * (F('product__product__price') 给出的结果是否大于12? Case 和 When 在这里没有用。我对吗?如果是这样,我如何在我的查询中实现这样的测试?
    • 检查这个问题和我的回答,听起来和你想要的差不多stackoverflow.com/a/42333766/2452074
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2018-04-21
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多