使用外键作为 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
这给了我恒定数量的查询,这是理想的。
我的模型关系如下所示:
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
这给了我恒定数量的查询,这是理想的。