2

我有一个看起来像这样的模型:

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

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

先感谢您。

4

2 回答 2

2

我没有玩过 grappelli,但在标准 django-admin 中我会考虑使用:ModelAdmin.raw_id_fields。限制是您不使用名称而是使用 pk 选择服务。

默认情况下,Django 的管理员使用选择框接口 () 来处理外键字段。有时您不希望产生必须选择所有相关实例以显示在下拉列表中的开销。

raw_id_fields 是一个字段列表,您希望将其更改为 ForeignKey 或 ManyToManyField 的 Input 小部件:

class ArticleAdmin(admin.ModelAdmin):
    raw_id_fields = ("newspaper",)

更难的方法是覆盖服务的管理员管理器并添加请求级缓存。记住要让这个管理器在访问相关对象时可用。

于 2011-07-03T15:29:11.243 回答
1

您需要覆盖管理查询集方法并在其中添加一个 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)

仅此一项应该会稍微减少您的查询,但主要问题是 Djangoselect_related不会自动遵循 ManyToMany。您需要为此做一些额外的解决方法。我会使用prefill_entry_listFeinCMS应用程序中的 来做到这一点。

于 2011-07-03T22:09:57.760 回答