【发布时间】:2015-04-20 07:31:56
【问题描述】:
假设我有一个模型MyModel,它的属性方法使用另一个模型的查询集。
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 上的get_queryset() 方法每次都查询数据库以为每一行生成list_other_model 变量。
这导致我的 MyModel ListView 生成数百个 SQL 查询。效率不高。
当使用MyModel.objects.all() 时,我如何构建一个Manager 或get_queryset 方法来缓存变量list_other_model 的每一行?
我希望我的问题是有道理的——我正在喝第六杯浓缩咖啡,但仍然没有找到减少数据库查询的方法。
【问题讨论】:
-
因为这个方法看起来很复杂,并且对实例来说是唯一的,所以你不会绕过每个实例的多个查询,除非你可以做一个查询,将它缓存在某个地方,然后在仅限蟒蛇。我建议改为考虑缓存
complex_attr的结果,这种方式可以在更改OtherModel时智能失效,例如基于MyModel的实例ID 和另一个版本构建complex_attr的缓存键保存时以OtherModel递增的数字。 -
@Yuji'Tomita'Tomita 好主意。下面看看我的回答。我想为每次视图刷新刷新
list_other_model,但不是为我的结果集中的每一行。你认为我的 ModelManager 方法能做到这一点吗?它似乎是。我想我会为它写一些测试。 -
MyModel和OtherModel之间是否有任何关系(例如ForeignKey)?或者您总是必须使用OtherModel.objects.all()而不进行任何过滤? -
@Todor 不幸的是,没有关系。而且我确实需要“复杂算法”的整个 OtherModel 查询集。
-
好吧,我想您发布的内容是一个很好的解决方案。我能想到的另一种方法是使用函数而不是属性,因此函数可以简单地请求
OtherModelqueryset。 ->def get_complex_attr(self, other_model_queryset):
标签: django django-queryset django-managers