管理中的可翻译 Manytomany 字段生成许多查询
Translatable Manytomany fields in admin generate many queries
我正在使用 django-parler(django-hvad 的衍生物)进行翻译。在管理中显示具有多对多关系的外键字段时,django 为每个运行一个查询:
所以当有 300 个服务时,会有同样多的查询。
我认为 get_queryset 上的 prefetch_related 不适用于 mantomany
filters/lists,如有错误请指正:
def get_queryset(self, request):
return super(DoctorAdmin, self).get_queryset(request).prefetch_related('translations', 'services__translations')
对查询次数没有影响。在 parler 上启用缓存(正如作者建议 here)也无济于事,因为不会重复相同的查询,但这些过滤器上的每个项目都会在翻译项目的查询中被调用(每次 ID 都不同)。所以,我正在寻找的是内部过滤器上的 select_related/prefetch_related。我也会同时审查你的应用程序,以防你已经解决了这样的问题。
看起来你正在为多对多 table 使用双下划线,而它应该是单下划线。也可以尝试在 master table
中添加
尝试:
return super(DoctorAdmin, self).get_queryset(request).prefetch_related(
'services__service_translation__translations',
'services__service_translation__master'
)
显示 models.py 文件会有所帮助。
希望对其他人有用,以下是我解决问题的方法,将管理员中的查询从 2k 减少到 30:
class MyModelAdminForm(TranslatableModelForm):
class Meta:
model = MyModel
exclude = ()
def __init__(self, *args, **kwargs):
super(MyModelAdminForm, self).__init__(*args, **kwargs)
self.fields['services'].queryset = Service.objects.prefetch_related('translations').all()
class MyModelAdmin(TranslatableAdmin):
form = MyModelAdminForm
因此,覆盖表单,一旦进入内部,使用预取覆盖查询集。
我正在使用 django-parler(django-hvad 的衍生物)进行翻译。在管理中显示具有多对多关系的外键字段时,django 为每个运行一个查询:
所以当有 300 个服务时,会有同样多的查询。
我认为 get_queryset 上的 prefetch_related 不适用于 mantomany
filters/lists,如有错误请指正:
def get_queryset(self, request):
return super(DoctorAdmin, self).get_queryset(request).prefetch_related('translations', 'services__translations')
对查询次数没有影响。在 parler 上启用缓存(正如作者建议 here)也无济于事,因为不会重复相同的查询,但这些过滤器上的每个项目都会在翻译项目的查询中被调用(每次 ID 都不同)。所以,我正在寻找的是内部过滤器上的 select_related/prefetch_related。我也会同时审查你的应用程序,以防你已经解决了这样的问题。
看起来你正在为多对多 table 使用双下划线,而它应该是单下划线。也可以尝试在 master table
中添加尝试:
return super(DoctorAdmin, self).get_queryset(request).prefetch_related(
'services__service_translation__translations',
'services__service_translation__master'
)
显示 models.py 文件会有所帮助。
希望对其他人有用,以下是我解决问题的方法,将管理员中的查询从 2k 减少到 30:
class MyModelAdminForm(TranslatableModelForm):
class Meta:
model = MyModel
exclude = ()
def __init__(self, *args, **kwargs):
super(MyModelAdminForm, self).__init__(*args, **kwargs)
self.fields['services'].queryset = Service.objects.prefetch_related('translations').all()
class MyModelAdmin(TranslatableAdmin):
form = MyModelAdminForm
因此,覆盖表单,一旦进入内部,使用预取覆盖查询集。