使用 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)
我有一个模型,其中包含一个 @property
,我希望在执行以下操作时包含它
vals = MyModel.objects.values()
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)