【问题标题】:Translatable Manytomany fields in admin generate many queriesadmin 中可翻译的 Manytomany 字段生成许多查询
【发布时间】:2015-06-23 22:47:36
【问题描述】:

我正在使用 django-parler(django-hvad 的衍生物)进行翻译。在管理中显示具有多对多关系的外键字段时,django 为每个字段运行一个查询:

因此,当有 300 个服务时,查询数量就会一样多。

我认为 get_queryset 上的 prefetch_related 不适用于mantomany 过滤器/列表,如果我错了,请纠正我:

def get_queryset(self, request):
    return super(DoctorAdmin, self).get_queryset(request).prefetch_related('translations', 'services__translations')

对查询数量没有影响。在 parler 上启用缓存(正如作者建议的 here)也无济于事,因为不会重复相同的查询,但这些过滤器上的每个项目都会在查询翻译项目时被调用(ID 每次都不同)。所以,我正在寻找的是内部过滤器上的 select_related/prefetch_related 。同时,我也会审核您的应用程序,以防您已经解决了此类问题。

【问题讨论】:

    标签: python django django-admin django-hvad django-parler


    【解决方案1】:

    看起来您在多对多表中使用双下划线,而它应该是单下划线。也尝试在主表中添加

    试试:

    return super(DoctorAdmin, self).get_queryset(request).prefetch_related( 
        'services__service_translation__translations',
        'services__service_translation__master'
    )
    

    显示 models.py 文件会有所帮助。

    【讨论】:

    • 重点是 get_queryset 方法对为外键或多外键显示的过滤器没有影响。这些过滤器中的每一个都会执行“n”个查询以获取翻译名称。为这些下拉列表覆盖其查询集的方法是什么?
    【解决方案2】:

    希望对其他人有用,这是我解决问题的方法,将管理中的查询从 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
    

    所以,覆盖表单,一旦进入,用预取覆盖查询集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多