代码之家  ›  专栏  ›  技术社区  ›  N6151H

使用annotate()包括django模型对象属性

  •  4
  • N6151H  · 技术社区  · 6 年前

    我有一个模型,包括 @property 当我做这样的事情时 vals = MyModel.objects.values() Another S/O post 建议通过重写 get_queryset manager类的方法,并通过调用 annotate(xtra_field=...)

    问题是,我找不到如何使用模型属性执行此操作的示例。我试过这样的方法 super(SuperClass, self).get_queryset().annotate(xtra_fld=self.model.xtra_prop) 还有许多变化,但都不起作用。

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

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

    1 回复  |  直到 6 年前
        1
  •  6
  •   damon Curtis Snowden    6 年前

    除非在数据库中生成属性值,否则在不重写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)