prefetch_related()是 Django ORM 中用于优化查询性能的另一个重要方法,尤其在处理多对多(ManyToMany)关系和反向关系时非常有用。它允许你预加载相关对象,从而减少数据库查询次数。
Test/app13
python manage.py startapp app13
Test/Test/settings.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('app13/', include('app13.urls')), ]
Test/app13/models.py
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) authors = models.ManyToManyField(Author) class Review(models.Model): book = models.ForeignKey(Book, on_delete=models.CASCADE) rating = models.IntegerField()
Test/app13/views.py
from django.shortcuts import render from .models import Book, Author, Review def book_list(request): # 使用 prefetch_related 预加载作者和评论信息 books = Book.objects.prefetch_related('authors', 'review_set').all() # 准备传递给模板的上下文 context = { 'books': books, } # 渲染并返回响应 return render(request, '13/book_list.html', context)
Test/templates/13/book_list.html
Title {% for book in books %} {{ book.title }}
Authors:
{% for author in book.authors.all %} - {{ author.name }}
{% endfor %}
Reviews:
{% for review in book.review_set.all %} - Rating: {{ review.rating }}
{% endfor %}
{% endfor %}
Test/app13/urls.py
from django.urls import path from . import views urlpatterns = [ path('book_list/', views.book_list, name='book_list'), ]
Test/populate_db.py
import random import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Test.settings') django.setup() from app13.models import Author, Book, Review # 创建随机作者 for _ in range(10): author = Author(name=f'Author {_}') author.save() # 创建随机书籍 for _ in range(20): book = Book(title=f'Book Title {_}') book.save() # 随机选择1-3个作者 authors = Author.objects.all() book.authors.set(random.sample(list(authors), random.randint(1, 3))) # 创建随机评论 for _ in range(50): review = Review( book=random.choice(Book.objects.all()), rating=random.randint(1, 5) ) review.save()
http://127.0.0.1:8000/app13/book_list/