0
点赞
收藏
分享

微信扫一扫

Django Version 1.6 View source analysis about list.py


Source:​​Django Version 1.6 View source analysis about list.py​​

原址在上面 用Django 1.6搭建的 勉强能见人 嘿嘿 源码分析看起来是不靠谱的 反正就是酱油的很 

class MultipleObjectMixin(ContextMixin):

    """

    A mixin for views manipulating multiple objects.

    """

    allow_empty = True

    queryset = None # 产生数据的queryset

    model = None   # 如果存在model,而queryset不存在 则  queryset = self.model._default_manager.all() 

    paginate_by = None # 分页的每页数据项数

    paginate_orphans = 0

    context_object_name = None

    paginator_class = Paginator

    page_kwarg = 'page' # 用于判决时第几页 page=self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1



    def get_queryset(self):# 如果self.queryset存在则 返回如果存在model,而queryset不存在 则  queryset = self.model._default_manager.all() 

        """

        Get the list of items for this view. This must be an iterable, and may

        be a queryset (in which qs-specific behavior will be enabled).

若对于queryset无特殊要求 即只需要返回all()即可得 只需要赋值model的值即可

        """

        if self.queryset is not None:

            queryset = self.queryset

            if hasattr(queryset, '_clone'):

                queryset = queryset._clone()

        elif self.model is not None:

            queryset = self.model._default_manager.all()

        else:

            raise ImproperlyConfigured("'%s' must define 'queryset' or 'model'"

                                       % self.__class__.__name__)

        return queryset



    def paginate_queryset(self, queryset, page_size):# 根据 paginate_by作为分页的每页数据项数 ,并且指定页数page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1

        """

        Paginate the queryset, if needed.

        """

        paginator = self.get_paginator(

            queryset, page_size, orphans=self.get_paginate_orphans(),

            allow_empty_first_page=self.get_allow_empty())

        page_kwarg = self.page_kwarg

        page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1

        try:

            page_number = int(page)

        except ValueError:

            if page == 'last':

                page_number = paginator.num_pages

            else:

                raise Http404(_("Page is not 'last', nor can it be converted to an int."))

        try:

            page = paginator.page(page_number)

            return (paginator, page, page.object_list, page.has_other_pages())

        except InvalidPage as e:

            raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {

                                'page_number': page_number,

                                'message': str(e)

            })



    def get_paginate_by(self, queryset):

        """

        Get the number of items to paginate by, or ``None`` for no pagination.

        """

        return self.paginate_by



    def get_paginator(self, queryset, per_page, orphans=0,

                      allow_empty_first_page=True, **kwargs):

        """

        Return an instance of the paginator for this view.

        """

        return self.paginator_class(

            queryset, per_page, orphans=orphans,

            allow_empty_first_page=allow_empty_first_page, **kwargs)



    def get_paginate_orphans(self):

        """

        Returns the maximum number of orphans extend the last page by when

        paginating.

        """

        return self.paginate_orphans



    def get_allow_empty(self):

        """

        Returns ``True`` if the view should display empty lists, and ``False``

        if a 404 should be raised instead.

        """

        return self.allow_empty



    def get_context_object_name(self, object_list):# 返回 self.context_object_name 或者 hasattr(object_list, 'model')-->return '%s_list' % object_list.model._meta.model_name

        """

        Get the name of the item to be used in the context.

        """

        if self.context_object_name:

            return self.context_object_name

        elif hasattr(object_list, 'model'):

            return '%s_list' % object_list.model._meta.model_name

        else:

            return None



    def get_context_data(self, **kwargs): # 这个是为了get()函数self.object_list=get_query_set()--->queryset = kwargs.pop('object_list', self.object_list)

        """

        Get the context for this view.

        """

        queryset = kwargs.pop('object_list', self.object_list)

        page_size = self.get_paginate_by(queryset)

        context_object_name = self.get_context_object_name(queryset)

        if page_size:

            paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)

            context = {

                'paginator': paginator,

                'page_obj': page,

                'is_paginated': is_paginated,

                'object_list': queryset

            }

        else:

            context = {

                'paginator': None,

                'page_obj': None,

                'is_paginated': False,

                'object_list': queryset

            }

        if context_object_name is not None:

            context[context_object_name] = queryset

        context.update(kwargs)

        return super(MultipleObjectMixin, self).get_context_data(**context)





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)





class MultipleObjectTemplateResponseMixin(TemplateResponseMixin):

    """

    Mixin for responding with a template and list of objects.

    """

    template_name_suffix = '_list'



    def get_template_names(self):

        """

        Return a list of template names to be used for the request. Must return

        a list. May not be called if render_to_response is overridden.

        """

        try:

            names = super(MultipleObjectTemplateResponseMixin, self).get_template_names()

        except ImproperlyConfigured:

            # If template_name isn't specified, it's not a problem --

            # we just start with an empty list.

            names = []



        # If the list is a queryset, we'll invent a template name based on the

        # app and model name. This name gets put at the end of the template

        # name list so that user-supplied names override the automatically-

        # generated ones.

        if hasattr(self.object_list, 'model'):

            opts = self.object_list.model._meta

            names.append("%s/%s%s.html" % (opts.app_label, opts.model_name, self.template_name_suffix))



        return names





class ListView(MultipleObjectTemplateResponseMixin, BaseListView):

    """

    Render some list of objects, set by `self.model` or `self.queryset`.

    `self.queryset` can actually be any iterable of items, not just a queryset.

    """


举报

相关推荐

0 条评论