使用 annotate() 包含一个 Django 模型对象 属性

Include a django model object property using annotate()

我有一个模型,其中包含一个 @property,我希望在执行以下操作时包含它 vals = MyModel.objects.values() 建议实现此目的的方法是覆盖管理器 class 的 get_queryset 方法,并通过调用 annotate(xtra_field=...).

进行扩充

问题是我找不到关于如何使用模型 属性 执行此操作的示例。我试过类似的东西 super(SuperClass, self).get_queryset().annotate(xtra_fld=self.model.xtra_prop) 及其众多变体,none 其中有效。

我认为问题是注释参数的 RHS 应该是什么?

(而且,是的,我知道还有其他更笨拙的方法可以做到这一点,比如迭代 values() returns 并添加 属性 。只是不对我来说是一个非常优雅(甚至是 django)的解决方案。

除非您在数据库中生成 属性 值,否则您不能在不覆盖 Django 的内部方法的情况下执行此操作 – 我建议不要这样做

一个更优雅的解决方案可能是向 a custom queryset 添加一个额外的方法,它根据请求生成额外的字段:

from django.db import models

class AreaQuerySet(models.QuerySet):
    def values_with_area(self, *fields):
        # width & height are always required to calculate the area
        fields = set(fields)
        fields.update(['width', 'height'])

        for row in self.values(*fields):
            row['area'] = Widget.calculate_area(row['width'], row['height'])
            yield row

class Widget(models.Model):
    # ...
    objects = AreaQuerySet.as_manager()

    @classmethod
    def calculate_area(cls, width, height):
        return width * height

    @property
    def area(self):
        return Widget.calculate_area(self.width, self.height)