Django查询集,模型方法包含另一个查询集

Django查询集,模型方法包含另一个查询集,django,django-queryset,django-managers,Django,Django Queryset,Django Managers,假设我有一个模型,MyModel,其属性方法使用另一个模型的queryset class OtherModel(models.Model) ... class MyModel(models.Model): simple_attr = models.CharField('Yada yada') @property def complex_attr(self): list_other_model = OtherModel.objects.all()

假设我有一个模型,
MyModel
,其属性方法使用另一个模型的queryset

class OtherModel(models.Model)
    ...

class MyModel(models.Model):
    simple_attr = models.CharField('Yada yada')

    @property
    def complex_attr(self):
        list_other_model = OtherModel.objects.all()
        ...
        # Complex algorithm using queryset from 'OtherModel' and simple_attr
        return result
这会导致
MyModel
上的my
get\u queryset()
方法每次为每一行查询数据库以生成
list\u other\u model
变量

这导致MyModel
ListView
生成数百个SQL查询。效率不高

使用
MyModel.objects.all()
时,如何设计管理器或获取\u queryset方法来缓存每行的变量
list\u other\u model


我希望我的问题有意义——我已经喝了第六杯浓缩咖啡,但仍然没有找到减少数据库查询的方法。

不确定这是否是最好的方法,但它确实有效

如果有人给出更好的答案,我会接受他们的

class OtherModel(models.Model)
    ...

class MyModelManager(models.Manager):
    def get_queryset(self):
        self.model.list_other_model = OtherModel.objects.all()
        return super(MyModelManager, self).get_queryset()

class MyModel(models.Model):
    simple_attr = models.CharField('Yada yada')
    list_other_model = None

    objects = MyModelManager()

    @property
    def complex_attr(self):
        ...
        # Complex algorithm using queryset from 'OtherModel' and simple_attr
        return result

由于此方法看起来很复杂,并且对于实例来说是唯一的,因此您不会对每个实例进行多个查询,除非您可以执行单个查询,将其缓存到某个位置,并仅使用python执行进一步的操作。我建议您以一种可以在更改
其他模型时智能地失效的方式来缓存
复杂属性的结果,例如基于
MyModel
的实例ID为
复杂属性构建缓存键,还有另一个版本号,保存后由
OtherModel
递增。@Yuji'Tomita'Tomita极好的主意。看看下面我的答案。我想为每次视图刷新刷新
列表\其他\模型
,但不是为结果集中的每一行。您认为我的ModelManager方法可以实现这一点吗?看来是的。我想我会为此编写一些测试。
MyModel
OtherModel
之间是否存在任何关系(例如
ForeignKey
)?或者您总是必须使用
OtherModel.objects.all()
而不进行任何过滤?@Todor,不幸的是,没有关系。我确实需要“复杂算法”的整个OtherModel查询集。那么我想你发布的是一个很好的解决方案。我可以想到的另一种方法是使用函数而不是属性,这样函数就可以简单地请求
OtherModel
queryset
->-><代码>定义获取复杂属性(自身、其他模型查询集):