django通用视图的ListView

5 篇文章 0 订阅
3 篇文章 0 订阅

list

list模块与detail模块是很相似的,两者的区别是detail.SingleObjectMixin.get_object()过滤queryset来获取单个对象,而list.MultipleObjectMixin只是对queryset根据提供ordering字段进行排序,由于queryset包含多个对象,所以提供了分页相关的功能。

MultipleObjectMixin

MultipleObjectMixin和SingleObjectMixin的区别:SingleObjectMixin处理的数据是单一的,而

MultipleObjectMixin是多个的且需要分页的

主要代码为:

class MultipleObjectMixin(ContextMixin):
"""A mixin for views manipulating multiple objects."""
    allow_empty = True #是否允许返回的object_list为空
    queryset = None 
    model = None
    paginate_by = None #(与分页相关)每页的item数目,就是Paginator.per_age
    paginate_orphans = 0 #(与分页相关)就是Paginator.orphans
    context_object_name = None # context中的obejct_list的名字
    paginator_class = Paginator
    page_kwarg = 'page'
    ordering = None	# 排序字段

    def get_queryset(self):
        """
        Return the list of items for this view.

        The return value must be an iterable and may be an instance of
        `QuerySet` in which case `QuerySet` specific behavior will be enabled.
        """
        if self.queryset is not None:
            queryset = self.queryset
            if isinstance(queryset, QuerySet):
                queryset = queryset.all()
        elif self.model is not None:
            queryset = self.model._default_manager.all()
        else:
            raise ImproperlyConfigured(
                "%(cls)s is missing a QuerySet. Define "
                "%(cls)s.model, %(cls)s.queryset, or override "
                "%(cls)s.get_queryset()." % {
                    'cls': self.__class__.__name__
                }
            )
        ordering = self.get_ordering()
        if ordering:
            if isinstance(ordering, str):
                ordering = (ordering,)
            queryset = queryset.order_by(*ordering)

        return queryset

    def get_context_data(self, *, object_list=None, **kwargs):
        """Get the context for this view."""
        queryset = object_list if object_list is not None else 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().get_context_data(**context)

重写了父类的get_context_data方法,其上下文为

context = {
                'paginator': paginator,
                'page_obj': page,
                'is_paginated': is_paginated,
                'object_list': queryset
            }

BaseListView

BaseListView组合MultipleObjectMixin和View,实现处理get请求和请求分发(dispatch)

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 = not self.object_list
            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)

MultpleObjectTemplateResponseMixin

MultpleObjectTemplateResponseMixin主要是获取上下文并返回响应重写了get_template_names方法,也就是其模板的名字是

app_label + model_name(小写) + template_name_suffix(_detail)

ListView

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值