使用外键作为 django 管理界面中的列是否为每一行创建一个新的数据库查询?

Does using a foreign key as a column in the django admin interface create a new database query for each row?

我的模型关系如下所示:

class Author(Model):
    first_name = CharField()

class Book(Model):
    title = CharField()
    author = ForeignKey(Author)

我想要这样的管理界面:

class BookAdmin(ModelAdmin):
    list_display = ('title', 'author_name')

    def author_name(self, obj):
        return obj.author.name

这是为每一行创建一个新查询,还是 django 聪明地在这里使用连接?如果关系是 2 层或更多层而不是 1 层怎么办?

使用 python 3.8、django 3.1 和 Postgres 12。

查看文档常见问题解答:“How can I see the raw SQL queries Django is running?

确保您的 Django DEBUG 设置设为 True。然后这样做:

from django.db import connection
print(connection.queries)

这为您提供了 Django 执行的所有 SQL 查询。从那里您可以检查它是使用连接还是对 ForeignKey

使用单独的查询

刚刚对此进行了测试,是的,它似乎为每一行创建了一个新查询。要确认,您可以在设置中使用 DEBUG = True 并执行如下操作:

class BookAdmin(ModelAdmin):
    list_display = ('title', 'author_name')

    def author_name(self, obj):
        name = obj.author.name
        from django.db import connection
        print(len(connection.queries))
        return name

这将在呈现一行时打印 运行 的查询数。您可以观察到它随着行的呈现而增加。

幸运的是,您可以覆盖 get_queryset 以添加 select_related,以改进查询,因此:

class BookAdmin(ModelAdmin):
    list_display = ('title', 'author_name')

    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        return queryset.select_related('author')

    def author_name(self, obj):
        return obj.author.name

这给了我恒定数量的查询,这是理想的。