Django使用多对多关系中的值对查询进行注释

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

以下是Django的多对多关系示例:

我希望能够在Django Admin中显示文章listview上的一列,其中包含相关出版物的标题。因此,如果我有一篇文章
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])

非常感谢!工作完美。