Python 如何在django中创建查询较少的视图

Python 如何在django中创建查询较少的视图,python,django,django-views,django-queryset,Python,Django,Django Views,Django Queryset,Models.py class Book(models.Model): created_at = models.DateTimeField(auto_now_add=True, editable=False) name = models.CharField(max_length=255, unique=True) slug = models.SlugField(max_length=255, blank=True, default='', unique=True) class Bo

Models.py

class Book(models.Model):
  created_at = models.DateTimeField(auto_now_add=True, editable=False)
  name = models.CharField(max_length=255, unique=True)
  slug = models.SlugField(max_length=255, blank=True, default='', unique=True)

class BookTranslation(models.Model):
  book = models.ForeignKey(Book, related_name='book_translations')
  language = models.CharField(max_length=2, choices=LANGUAGE_CHOICES)

class Chapter(models.Model):
  chapter = models.IntegerField()
  book_translation = models.ForeignKey(BookTranslation, related_name='related_chapters')

class Page(models.Model):
  chapter = models.ForeignKey(Chapter, related_name='related_pages')
  page = models.IntegerField()
  url = models.CharField(max_length=255)
url.py

url(r'^(?P<language>[\w-]{2})-book/(?P<slug>[\w-]+)/(?P<chapter>\d+)/(?P<page>\d+)/$",
  PageView(), 
  name="page")
但是这样,每次我打开这个页面,我都会向DB发出6个请求,当我可以很容易地获得上下文['book']、上下文['book_translation']context['chapter']和上下文['page']中的参数时,使用如下单孔SQL查询:

SELECT *
FROM Book b, BookTranslation bt, Chapter c, Page p
WHERE b.slug=self.kwargs['slug'] and 
  b.name=bt.book_id and
  bt.language=self.kwargs['language'] and 
  c.book_translation_id=bt.id and
  c.chapter=self.kwargs['chapter'] and 
  c.id=p.chapter_id and 
  p.page=self.kwargs['page']

有人能告诉我如何使这个视图(最好是基于类的)更具性能吗?我可能不明白它们是如何工作的…

如果您想检索相关外键,请使用
通过覆盖
SingleObjectMixin
get\u queryset
如下所示:

class PageView(DetailView):

    ...

    def get_queryset(self, *args, **kwargs):
        qs = super(PageView, self).get_queryset(*args, **kwargs)
        return qs.select_related()
这将在单个查询中获取所有相关对象,因此只要未计算queryset,就不应再次查询视图的
get\u context\u data
中的所有相关对象

参考:

class PageView(DetailView):

    ...

    def get_queryset(self, *args, **kwargs):
        qs = super(PageView, self).get_queryset(*args, **kwargs)
        return qs.select_related()