prefetch_related_objects
进行营救。
从Django 1.10开始 (注意:它仍然存在于以前的版本中,但不是公共API的一部分。) ,我们可以使用prefetch_related_objects来划分和解决问题。
prefetch_related
是一个操作,其中的Django获取相关数据 的查询集已经被评估(做主要的一个之后的第二查询求值)。并且为了工作,它希望查询集中的项目是同质的(相同类型)。反向通用生成现在无法正常工作的主要原因是,我们具有来自不同内容类型的对象,并且代码还不够智能,无法区分不同内容类型的流。
现在,prefetch_related_objects
我们仅在查询 进行访存,在该 上所有项目都是同质的。这是一个例子:
from django.db import models
from django.db.models.query import prefetch_related_objects
from django.core.paginator import Paginator
from django.contrib.contenttypes.models import ContentType
from tags.models import TaggedItem, Book, Movie
tagged_items = TaggedItem.objects.all()
paginator = Paginator(tagged_items, 25)
page = paginator.get_page(1)
# prefetch books with their author
# do this only for items where
# tagged_item.content_object is a Book
book_ct = ContentType.objects.get_for_model(Book)
tags_with_books = [item for item in page.object_list if item.content_type_id == book_ct.id]
prefetch_related_objects(tags_with_books, "content_object__author")
# prefetch movies with their director
# do this only for items where
# tagged_item.content_object is a Movie
movie_ct = ContentType.objects.get_for_model(Movie)
tags_with_movies = [item for item in page.object_list if item.content_type_id == movie_ct.id]
prefetch_related_objects(tags_with_movies, "content_object__director")
# This will make 5 queries in total
# 1 for page items
# 1 for books
# 1 for book authors
# 1 for movies
# 1 for movie directors
# Iterating over items wont make other queries
for item in page.object_list:
# do something with item.content_object
# and item.content_object.author/director
print(
item,
item.content_object,
getattr(item.content_object, 'author', None),
getattr(item.content_object, 'director', None)
)