django get_queryset()是多余的,因为我们有get_context_data()?

时间:2022-08-17 19:22:48

I have been always wondering if get_queryset() is redundant in django. As we know, get_queryset() returns a list of objects back to the page, but to return this list of objects, we can also always specify it in get_context_data(), and get_context_data() can return many more variables, not just a list. An example can be seen as follows:

我一直想知道django中get_queryset()是否是多余的。我们知道,get_queryset()返回一个返回页面的对象列表,但是为了返回这个对象列表,我们也可以在get_context_data()中指定它,get_context_data()可以返回更多的变量,而不仅仅是一个列表。一个例子可以看作如下:

Return a list of children book by get_queryset()

通过get_queryset()返回子书列表

from django.views.generic import ListView
from books.models import Book

class ChildrenBook(ListView):
    model = Book
    def get_queryset(self, *args, **kwargs):
        qset = super(BookListView, self).get_queryset(*args, **kwargs)
        return qset.filter(type="children")

Return a list of children book by get_context_data()

通过get_context_data()返回子书列表

from django.views.generic import ListView
from books.models import Book

class ChildrenBook(ListView):
    model = Book
    def get_context_data(self, **kwargs):
        context = super(PublisherDetail, self).get_context_data(**kwargs)
        context['children_book_list'] = Book.objects.filter(type="children")
        return context

To the best of my knowledge, I do not find anything that get_queryset() can do but get_context_data cannot. Anyone can find some situation where only get_queryset() can be used and illustrate its necessity?

据我所知,我没有找到任何get_queryset()可以做但get_context_data不能做的事情。任何人都可以找到一些只能使用get_queryset()并说明其必要性的情况?

1 个解决方案

#1


0  

If you take a look at the actual django source code you’ll see why overloading only get_context_data is a bad idea unless you want to have to rewrite a whole bunch of code:

如果你看看实际的django源代码,你就会明白为什么只重载get_context_data是一个坏主意,除非你想要重写一大堆代码:

class BaseListView(MultipleObjectMixin, View):
    """
    A base view for displaying a list of objects.
    """
    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()
        allow_empty = self.get_allow_empty()

        if not allow_empty:
            # When pagination is enabled and object_list is a queryset,
            # it's better to do a cheap query than to load the unpaginated
            # queryset in memory.
            if (self.get_paginate_by(self.object_list) is not None
                    and hasattr(self.object_list, 'exists')):
                is_empty = not self.object_list.exists()
            else:
                is_empty = len(self.object_list) == 0
            if is_empty:
                raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.")
                        % {'class_name': self.__class__.__name__})
        context = self.get_context_data()
        return self.render_to_response(context)

Essentially, not overloading the get_queryset method won’t handle cases like when there are no records in the filter because the object_list property won’t be set correctly.

本质上,不重载get_queryset方法将不会处理过滤器中没有记录的情况,因为object_list属性将无法正确设置。

#1


0  

If you take a look at the actual django source code you’ll see why overloading only get_context_data is a bad idea unless you want to have to rewrite a whole bunch of code:

如果你看看实际的django源代码,你就会明白为什么只重载get_context_data是一个坏主意,除非你想要重写一大堆代码:

class BaseListView(MultipleObjectMixin, View):
    """
    A base view for displaying a list of objects.
    """
    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()
        allow_empty = self.get_allow_empty()

        if not allow_empty:
            # When pagination is enabled and object_list is a queryset,
            # it's better to do a cheap query than to load the unpaginated
            # queryset in memory.
            if (self.get_paginate_by(self.object_list) is not None
                    and hasattr(self.object_list, 'exists')):
                is_empty = not self.object_list.exists()
            else:
                is_empty = len(self.object_list) == 0
            if is_empty:
                raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.")
                        % {'class_name': self.__class__.__name__})
        context = self.get_context_data()
        return self.render_to_response(context)

Essentially, not overloading the get_queryset method won’t handle cases like when there are no records in the filter because the object_list property won’t be set correctly.

本质上,不重载get_queryset方法将不会处理过滤器中没有记录的情况,因为object_list属性将无法正确设置。