【发布时间】:2017-10-19 14:43:43
【问题描述】:
我有以下(简化的)模型结构:
class Article(Model):
@property
def article_number(self) -> str:
return self.attributes.get(masterdata_type__code='article_number').value
class Attribute(Model):
article = ForeignKey(Article, null=True, blank=True, related_name='attributes')
masterdata_type = ForeignKey(Type, related_name='attributes')
value = CharField(max_length=256, blank=True, db_index=True)
class Type(Model):
code = models.CharField(max_length=32)
在管理面板中,我想显示 100 篇文章的列表并显示其 article_number。现在这会导致 100 次数据库调用(我可以使用 Silk 监控看到),所以我想预取这些对象。我在管理面板中尝试了以下解决方案,但都不起作用。在这里减少数据库调用次数的正确方法是什么?
我正在使用带有 PostgreSQL 后端的 Django 1.8.14。
不起作用的解决方案:
def get_queryset(self, request):
queryset = super(ArticleSetAdmin, self).get_queryset(request)
return queryset.prefetch_related('attributes__masterdata_type')
还有 100 次数据库调用。
def get_queryset(self, request):
queryset = super(ArticleSetAdmin, self).get_queryset(request)
return queryset.prefetch_related(
Prefetch('attributes', queryset=Attribute.objects.select_related('masterdata_type')))
还有 100 次数据库调用。
def get_queryset(self, request):
queryset = super(ArticleSetAdmin, self).get_queryset(request)
return queryset.prefetch_related(
Prefetch('attributes', queryset=Attribute.objects.prefetch_related('masterdata_type')))
还有 100 次数据库调用。
def get_queryset(self, request):
queryset = super(ArticleSetAdmin, self).get_queryset(request)
return queryset.select_related('attributes__masterdata_type')
错误,因为属性与文章是多对一关系。
【问题讨论】:
-
请贴出全文模型
-
您需要显示更多代码,因为它不是导致问题的 get_queryset。您是在视图或模板中查找相关对象吗?当您获取相关对象时,您是否在过滤某些内容 - 这些可能会触发额外的数据库调用。
-
最好的解决方案是安装 django-debug-toolbar,看看额外的查询是什么以及触发它们的代码行。
标签: django django-admin django-queryset