Python学习之路-随笔04 小插曲之Django通用视图

虽然欠了攒了好几篇没写,但是这个要写先记下来,太零碎了容易忘

函数视图

一路看过来一般用法无非是

1.HttpResponse

2.render

3.render_to_response

然后看到一个通用视图可以解决部分代码冗余问题。但是一开始看例子一脸懵逼(可能我找到的都是不爱写注释的人的文章)

内心:这啥呀?怎么就拿到数据了?怎么拿的?什么时候就传过去了呀?

比如这样,还需要改一下urls,改个pk主键上去就行

class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'


class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]

然后一头雾水

ListView

找了半天,在list.py里找到了一些端倪,首先是下面这个类

class MultipleObjectMixin(ContextMixin):
    """
    A mixin for views manipulating multiple objects.
    """
    allow_empty = True
    queryset = None
    model = None
    paginate_by = None
    paginate_orphans = 0
    context_object_name = None
    paginator_class = Paginator
    page_kwarg = 'page'
    ordering = None

这个类是根据get_queryset的指引找来的,继承自这个Mixin,发现这堆参数。结合群众的智慧,好了不瞎扯了

里面的template_name指定模板名称,context_object_name指定上下文变量,也就是要套入模板中的数据,然后还有一个就是model,数据来源,如果指定了model

那么该通用视图就变成了相当于model.objects.all(),从这个模型里把数据都拿出来,这样不是很好用,不友好。所以它给了一个get_queryset的方法来自定义上下文变量

默认的是下面这样,重写一下用就行了

    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, six.string_types):
                ordering = (ordering,)
            queryset = queryset.order_by(*ordering)

        return queryset
View Code

其他的方法用到再重新写

然后是

TemplateView

用法是一般只在需要返回一个模板的时候用,指定一下template_name就行,待补充。

DetailView

对比ListView和DetailView两者,ListView用来获取model中的所有数据,而DetailView是获得某个数据的详细信息,比如一张试卷,前者获得试卷的名称之类的简要信息,后者获取试卷的题目等详细信息

用这个就用到上面说的需要在urls改成传递主键值来进行查询。

参数也有这么一堆

class SingleObjectMixin(ContextMixin):
    """
    Provides the ability to retrieve a single object for further manipulation.
    """
    model = None
    queryset = None
    slug_field = 'slug'
    context_object_name = None
    slug_url_kwarg = 'slug'
    pk_url_kwarg = 'pk'
    query_pk_and_slug = False

其中pk_url_kwarg就是主键,然后里面有一个类似ListView中get_queryset的方法叫get_object。用法也类似

然后都有的添加额外的信息(模型以外的数据)的方法叫get_context_data。

然后类似的通用视图还有CreateView,UpdateView,FormView,DeleteView。。。作用嘛,看名字就好了

待补充吧。。。

posted @ 2018-09-22 00:30  小蜗_slose  阅读(95)  评论(0编辑  收藏  举报