【问题标题】:Django @property used in .aggregate().aggregate() 中使用的 Django @property
【发布时间】:2018-10-24 19:05:30
【问题描述】:

我正在尝试从模型中聚合整数列表。整数派生的字段是@property 装饰器字段。装饰器按预期工作,并且在 template.html 内,如果直接传递,则显示没有问题。但是,如果我尝试通过.aggregate() 传递@property 字段,则传递给template 的上下文会抛出一个错误,基本上是Cannot resolve keyword 'sum_thing' into field.,后跟不包含任何装饰器字段的模型字段列表.

我的问题是 - 如何从模型中聚合(总和)派生字段?

#models.py

class Foo(models.Model):
    a = 10      # a & b are both
    b = 5       # models.IntegerField() items

    @property
    def sum_thing(self):
        return self.a - self.b

#views.py

class Bar(generic.ListView):

    def get_context_data(self, **kwargs):

        qs = Foo.object.all()

        totals = {}

        totals['sumthing'] = qs.aggregate(total=Sum('sum_thing')

        context = {
            'totals': totals
        }

        return context

** 我已经大大简化了models.pyviews.py

【问题讨论】:

    标签: python django python-3.x django-views


    【解决方案1】:

    您不能使用属性进行聚合,因为它在数据库中不存在。但是,您可以借助 Django 的 F 表达式对查询进行注释,以获取这些字段的实际值。请参阅下面的示例。

    from django.db.models import F, Sum
    
    Foo.objects.annotate(sum_a_and_b=F('a') + F('b')).aggregate(total=Sum('sum_a_and_b'))
    

    你也可以用 F 做任何数学运算,比如 / * + -,你也可以这样做

    .annotate(answer=F('a') + F('b') * 2)
    

    【讨论】:

    • 为了我的澄清 - .annotate() 基本上是重新计算 @property 函数。然后.aggregate() 方法对注释进行“求和”。换句话说,如果不需要直接调用装饰器的结果,这些计算都可以在形成上下文返回时完成。再次感谢。
    • 如果你做了注释,之后你也可以调用它。如果你注释数据库计算你的结果,如果你这样做@property python 计算结果。只有它是差异
    • 谢谢,很有帮助
    猜你喜欢
    • 2011-06-01
    • 2023-01-03
    • 2020-02-21
    • 2019-05-24
    • 2018-05-30
    • 2023-02-24
    • 2020-01-09
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多