Django函数视图升级到类视图

1,什么时候用类,什么时候用函数?

只要代码逻辑被重复使用,同时有需要共享的数据,则可以封装出一个类,这样可以享用类提供的好处----继承和复用。如果这种情况下依旧使用函数的话,就要定义多个子函数,通过函数级别的复用达到目的,但问题在于不够结构化,无法通过继承类,然后修改配置,或者重写某个方法达到目的

2,理解class-based view

django提供了以下几个class-based view

<1>View 基础的view,它基于Http方法的分发逻辑,比如get请求会调用相应的get方法,post请求会调用post方法,但自己没有实现具体的get或者post方法

<2>TemplateView,继承自View,可以直接用来返回指定的模板。它实现了get方法,直接传递变量到模板中实现数据展示

<3>List View,实现了get方法,可通过绑定模板批量获取数据

<4>Detail View,实现了get方法,可以绑定某一模板,来获取单个实例的数据

示例:

#1,function view
def my_view(request):
    if request.method == 'GET':
        ......

#2,class-based view
class my_view(View):
    def get(self,request):
        ....

好处:解耦了Http GET请求及其他请求,如果要增加处理post请求的逻辑,只需要增加函数def post即可

3,Detail View

<1>示例

from django.views import generic
class DetailView(generic.DetailView):
    model = Article
    template_name = 'blog/detail.html'
    context_object_name = 'article'

我们只是继承了DetailView,配置了model与template_name,就能渲染数据,因为对于单个数据的请求,Django帮我们封装好了数据获取的逻辑,我们秩序配置即可

<2>常用属性及接口
属性:
model:指定当前View要用的Model
queryset:与model一样,设定基础的数据集,但model设定无过滤功能
templage:模板名称
context_object_name:获取要用于对象的名称
接口:
get_queryset:用来获取数据
get_object:根据url参数,从queryset上获取对应实例
get_context_data:获取渲染到模板中的所有上下文

<3>url定义

from .views import DetailView
url(r'^article/(?P<pk>\d+)/$',DetailView.as_view(),name='detail'),#文章详情

通过as_view()函数来接受请求并返回响应(下面会讲到as_view())
指定了要匹配的参数pk作为过滤post数据的参数,从而产生了这样的请求:
Post.objects.filter(ok=pk),以拿到文章的实例

4,ListView

<1>示例

   class IndexView(generic.ListView):
        model=Article
        template_name='blog/index.html'
        context_object_name='articles'
        paginate_by=5

<2>常用属性及接口
paginate_by指定了每页显示多少条数据
get_ordering接口:返回用于queryset排序的一个或多个字段

def get_ordering(self):
    ordering = super(IndexView, self).get_ordering()
    #self.kwargs的数据是我们从url定义中拿到的
    sort = self.kwargs.get('sort')
    if sort == 'v':
        return ('-views', '-update_date', '-id')
    return ordering
    
#url定义
url(r'^category/(?P<slug>[\w-]+)/hot/$', CategoryView.as_view(), {'sort': 'v'},
        name='category_hot'),

get_queryset接口用来获取数据

#解决主页文章列表显示n+1问题
def get_queryset(self,**kwargs):
    queryset=super(IndexView,self).get_queryset()
    return queryset.select_related('author','category')

5,django中的view如何处理请求

django接受一个请求后(严格说是http请求,不过http请求会被django转化为request对象),请求会先经过所有middleware的process_request方法,然后解析url,接着根据配置的url和view的映射,把request对象传递到view中,view有两种:
<1>funciton view处理的逻辑比较好理解,就是简单的函数,流程就是函数的执行流程,只是第一个参数是request对象
<2>class-based view对外暴露的接口是as_view(),as_view()其实只做了一件事,那就是返回一个闭包,这个闭包会在django解析完之后调用,这个闭包会给class(我们定义的view)赋值,如reqeuts,args,kwargs,然后根据http方法分发请求,如get请求会调用class.get方法,post请求会调用class.post方法
请求到达后(如get请求)
用dispatch分发,接着调用get方法
在get请求中,先调用get_queryset方法,拿到数据源
然后调用get_context_data,拿到要渲染到模板中的数据(此时可以传一些额外的内容到网页),在get_context_data中,先调用get_paginate_by拿到每页数据,然后调用get_context_object_name拿到queryset名称,然后调用paginate_queryset进行分页处理,最后拿到的数据转化为dict并返回
调用render_to_response渲染数据到页面,在render_to_response中调用get_template_names拿到模板名,然后把request,context,template_name等传递到模板中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值