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)
urls.py
url(r'^(?P<language>[\w-]{2})-book/(?P<slug>[\w-]+)/(?P<chapter>\d+)/(?P<page>\d+)/$",
PageView(),
name="page")
我尝试了不同的方法来制作PageView()并最终得到了这个:
class PageView(DetailView):
model = Book
template_name = 'bookinfo/book_page.html'
context_object_name = 'book'
def get_context_data(self, **kwargs):
context = super(PageView, self).get_context_data(**kwargs)
context['book_translation'] = BookTranslation.objects.get(
book=context['book'], language=self.kwargs['language'])
context['chapter'] = Chapter.objects.get(
book_translation=context['book_translation'].id, chapter=self.kwargs['chapter'])
context['page'] = Page.objects.get(
chapter=context['chapter'].id, page=self.kwargs['page'])
context['chapter_list'] = Chapter.objects.filter(
book_translation=context['book_translation'].id)
context['page_list'] = Page.objects.filter(
chapter=context['chapter'].id)
return context
但是这样,每当我打开这个页面时,我向DB发出6个请求,当我可以轻松地在上下文['book'],context ['book_translation'] context ['chapter']中获取参数时context ['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']
有人可以解释一下我如何才能使这个View(最好是基于类)的性能更高?我可能不明白它们是如何工作的......
答案 0 :(得分:0)
如果要检索相关的外键,请使用select_related
覆盖get_queryset
SingleObjectMixin
,如下所示:
class PageView(DetailView):
...
def get_queryset(self, *args, **kwargs):
qs = super(PageView, self).get_queryset(*args, **kwargs)
return qs.select_related()
这将获取单个查询中的所有相关对象,因此只要不评估查询集,就不应再次查询视图get_context_data
中的所有相关对象。
参考:https://docs.djangoproject.com/en/1.6/ref/models/querysets/#select-related