我的模型看起来像这样:
class ParentObject(models.Model):
...
services = models.ManyToManyField(Service)
class ChildObject(models.Model):
parent = models.ForeignKey(ParentObject)
services = models.ManyToManyField(Service)
class Service(models.Model):
name = ...
description = ...
因此,总而言之,对象具有附加的服务列表,并且子对象必须附加其他服务。
在规模上,每个家长都有50-60个服务列表,每个孩子(每个家长5个)有30-40个服务列表。在django-admin(使用grappelli btw)我已将Child设置为内联。
问题是admin中的页面加载非常困难(3-5秒),因为Django Admin执行大约1200次查询(每次获取服务 - 有时多次)以显示要编辑的信息。
你知道优化这个的任何提示/技巧吗?
提前谢谢。
答案 0 :(得分:2)
我没有和grappelli一起玩,但在标准的django-admin中我会考虑使用:ModelAdmin.raw_id_fields。 限制是您不使用名称选择服务,而是使用pk。
默认情况下,Django的管理员使用 select-box interface()for ForeignKey的字段。有时 你不想承担开销 必须选择所有相关的 要在下拉列表中显示的实例。
raw_id_fields是您的字段列表 想改成输入 用于ForeignKey或的小部件 ManyToManyField:
class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)
更难的方法是覆盖服务的管理员管理器并添加请求级缓存。请记住,在获得高兴的对象时,可以使用该经理。
答案 1 :(得分:1)
您需要覆盖admin queryset方法并在其中添加select_related,将其放入admin.py文件中
class ServiceAdmin(admin.ModelAdmin):
...
def queryset(self, request):
qs = super(ServiceAdmin, self).queryset(request)
return qs.select_related()
admin.site.register(Service, ServiceAdmin)
仅此一点可以减少您的查询,但主要问题是Django select_related
不会自动跟随ManyToMany。您需要为此做一些额外的解决方法。我会使用FeinCMS应用程序中的prefill_entry_list
来执行此操作。