在 Django 管理界面中,如果你直接在列表视图中使用外键字段,Django 默认会为每一行执行一个新的数据库查询来获取外键关联的对象。这种现象被称为 N+1 查询问题,其中 N 是列表中的行数。例如,如果你有一个包含外键的模型,并且在管理界面的列表中显示这个外键,那么对于列表中的每一行,Django 都会执行一个额外的查询来获取外键指向的对象。
select_related
或 prefetch_related
方法来优化查询。为了避免 N+1 查询问题,可以使用 Django 提供的 select_related
和 prefetch_related
方法来优化查询。
select_related
select_related
用于单对一关系或外键关系,它会在执行查询时立即获取关联的对象,从而减少查询次数。
class MyModelAdmin(admin.ModelAdmin):
list_display = ('id', 'foreign_key_field')
def get_queryset(self, request):
queryset = super().get_queryset(request)
return queryset.select_related('foreign_key_field')
prefetch_related
prefetch_related
用于多对多关系或多对一关系,它会在 Python 层面上进行额外的查询来获取关联的对象,从而减少数据库查询次数。
class MyModelAdmin(admin.ModelAdmin):
list_display = ('id', 'foreign_key_field')
def get_queryset(self, request):
queryset = super().get_queryset(request)
return queryset.prefetch_related('foreign_key_field')
假设我们有两个模型 Author
和 Book
,其中 Book
模型有一个指向 Author
的外键。
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
在 Django 管理界面中,我们可以这样优化查询:
from django.contrib import admin
from .models import Book
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'author_name')
def author_name(self, obj):
return obj.author.name
def get_queryset(self, request):
queryset = super().get_queryset(request)
return queryset.select_related('author')
admin.site.register(Book, BookAdmin)
通过这种方式,Django 会在一次查询中获取所有需要的 Author
对象,从而避免了 N+1 查询问题。
在 Django 管理界面中使用外键作为列时,默认情况下会为每一行创建一个新的数据库查询。为了避免这个问题,可以使用 select_related
或 prefetch_related
方法来优化查询,从而提高应用程序的性能和响应速度。
没有搜到相关的文章