避免在django admin嵌套细节内联中进行n+1查询

rdlzhqv9  于 2023-10-21  发布在  Go
关注(0)|答案(1)|浏览(101)

我目前有一个模型在我的管理与一个孩子内联:

class ChildInline(admin.StackedInline):
   # displays fields that load other associations

@admin.register(Statistic)
class ParentAdmin(admin.ModelAdmin):
   inlines = (
        ChildInline,
   )

这导致了一个n+1问题,如果我能让它工作的话,这个问题可以很容易地用prefetch_related解决!我试过在子方法和父方法get_queryset上使用prefetch_related(以及其他方法),但没有消除n+1问题。
有人有这方面的工作代码吗?

kq4fsx7k

kq4fsx7k1#

您可以重写get_queryset()方法来获取关系字段,一个可能的解决方案可能是...
单位:views.py:

def get_queryset(self):
    single_related_fields = [field for field in self.model._meta.fields\
        if field.get_internal_type() in ['ForeignKey', 'OneToOneField']]
    multiple_related_fields = [field for field in self.model._meta.fields\
        if field.get_internal_type() in ['ManyToManyField']]
    return Model.objects.all().\
            select_related(single_related_fields).\
            prefetch_related(multiple_related_fields)

如果self.model给出错误,请在视图集中包含model或尝试使用self.__ class__.model,这可能会解决问题
您可以尝试根据自己的意愿调整字段,例如包含ManyToOneField或排除某些字段。
不建议在一对一或外键上使用prefetch_related。你应该使用select_related,它只需要db查询来获取键。
选择相关
预取相关

相关问题