Django与M2M的表现

时间:2011-07-03 12:34:17

标签: django django-admin django-grappelli

我的模型看起来像这样:

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次查询(每次获取服务 - 有时多次)以显示要编辑的信息。

你知道优化这个的任何提示/技巧吗?

提前谢谢。

2 个答案:

答案 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来执行此操作。