Django使用多对多关系中的值对查询进行注释
以下是Django的多对多关系示例: 我希望能够在Django Admin中显示文章listview上的一列,其中包含相关出版物的标题。因此,如果我有一篇文章Django使用多对多关系中的值对查询进行注释,django,django-models,django-admin,Django,Django Models,Django Admin,以下是Django的多对多关系示例: 我希望能够在Django Admin中显示文章listview上的一列,其中包含相关出版物的标题。因此,如果我有一篇文章a1,其中有出版物: Publication(title='Pub 1') Publication(title='Pub 2') 我想在管理列表视图中看到一列,显示“Pub 1,Pub 2”。我可以通过Admin类上的自定义函数来实现这一点: class ArticleAdmin(admin.ModelAdmin): list_d
a1
,其中有出版物:
Publication(title='Pub 1')
Publication(title='Pub 2')
我想在管理列表视图中看到一列,显示“Pub 1,Pub 2”
。我可以通过Admin类上的自定义函数来实现这一点:
class ArticleAdmin(admin.ModelAdmin):
list_display = ['publication_titles']
def publication_titles(self, obj):
return ', '.join([pub.title for pub in obj.publications.all()])
但这是一个N+1问题:每个文章行将对每个关联发布执行一个查询。我在Django调试工具栏中看到了这一点,在listview中呈现24篇文章时,执行的SQL查询数量从9个查询增加到33个
我想也许我可以在queryset中执行预回迁\u related
:
class ArticleAdmin(admin.ModelAdmin):
list_display = ['publication_titles']
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset.prefetch_related('publications')
return queryset
def publication_titles(self, obj):
return ', '.join([pub.title for pub in obj.publications.all()])
但这似乎对执行的SQL查询数量没有影响
我想我可以使用annotate()
来注释管理中使用的查询集,但我正在努力想办法。就像我想做的那样:
class ArticleAdmin(admin.ModelAdmin):
list_display = ['publication_titles']
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset.annotate(publication_titles=<HOW DO I GENERATE THE COLLECTION OF TITLES>)
return queryset
class-ArticleAdmin(admin.ModelAdmin):
列表显示=[“出版物标题”]
def get_queryset(自我,请求):
queryset=super()。获取\u queryset(请求)
queryset.annotate(出版物标题=)
返回查询集
但我不是在摸索我为
准备的东西
如何在不增加数据库查询数量的情况下获得显示的出版物列表?
QuerySet
s是不可变的,这意味着.prefetch\u related
将创建一个新的QuerySet
,您可以使用:
class ArticleAdmin(admin.ModelAdmin):
list_display = ['publication_titles']
def get_queryset(self, request):
return super().get_queryset(request).prefetch_related('publications')
def publication_titles(self, obj):
return ', '.join([pub.title for pub in obj.publications.all()])
class-ArticleAdmin(admin.ModelAdmin):
列表显示=[“出版物标题”]
def get_queryset(自我,请求):
return super().get_queryset(请求).prefetch_相关('publications'))
def出版物标题(自我、obj):
返回“,”join([obj.publications.all()中pub的pub.title])
非常感谢!工作完美。