一.Django的视图函数view
一个视图函数(类),简称视图,是一个简单的Python函数(类),它接受WEB请求并返回Web响应.
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片.
无论视图本身包含什么逻辑,都要返回响应.代码写在哪里也无所谓,只要它在你当前项目目录下面.除此之外没有更多要求了---可以说"没有什么神奇的地方".为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中.
一个简单的视图
下面是一个以HTML文档的形式返回当前日期和时间的视图:
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime(request): html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
代码的逐行解释:
1)首先从django.http模块导入HyypResponse类,以及Python的datetime库
2)接着定义了current_datetime函数.它就是视图函数.每个视图函数都使用HttpResponse对象作为第一个参数,并且通常称为request.
注意:视图函数的名称不重要;不需要用一个统一的命名方式来命名,以便让Django识别它我们将其命名为current_datetime,因为这个名称能够比较准确地反映出它实现的功能.
3)这个视图会返回一个HttpResponse对象,其中包含生成的响应.每个视图函数都负责返回一个HttpResponse对象
Django使用请求和响应对象来通过系统传递状态.
当浏览器向服务端请求一个页面时,Django创建一个HttpResponse对象,该对象包含关于请求的元数据.然后,Django加载相应的视图,将这个HTTPResponse对象作为第一个参数传递给视图函数.
每个视图负责返回一个HttpResponse对象.
views.py(视图层),熟练掌握两个对象:请求对象(request)和响应对象(HTTPResponse)
二.CBV和FBV
FBV(function base views) 就是在视图中使用函数处理请求
CBV(class base views) 就是在视图里使用类处理请求
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承,封装,多态).所以Django在后来加入了Class-Based-VieW.可以让我们用类写view.
优点:
1.提高代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
2.可以用不同的函数针对不同的HTTp方法处理,而不是通过很对if判断,提高代码的可读性
如果我们要写一个处理GET方法的view,用函数写的话是下面这样
from django.http import HttpResponse def my_view(request): if request.method == 'GET': return HttpResponse('OK')
如果用class-based-view写的话,就是下面:
from django.http import HttpResponse from django.views import View class MyView(View): def get(self,request): return HttpRsponse('ok')
Django的URL 是将一个请求分配给可调用函数的,而不是一个class.针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个类方法,会创建一个类的实例,然后通过这个实例调用dispatch()方法,dispath()方法会根据request的method的不同调用相应的方法来处理request(如get(),或者post()),到这里,这些方法和function-based-view差不多了,要接收request,得到了一个response返回.返回方法没有定义,会抛出HttpResponseNotAllowed异常。
注意:使用CBV时,urls.py中也做对应的修改:
# urls.py from django.conf.urls import url from myapp.views import MyView #引入我们在views.py里面创建的类 urlpatterns = [ url(r'^index/$', MyView.as_view()), ]
CBV传参,和FBV类似,有名分组,无名分组
url写法:无名分组的
url(r'^cv/(\d{2})/', views.Myd.as_view(),name='cv'), url(r'^cv/(?P<n>\d{2})/', views.Myd.as_view(name='xxx'),name='cv'),
#如果想给类的name属性赋值,前提你的Myd类里面必须有name属性(类属性,
定义init方法来接受属性行不通,但是可以自行研究一下,看看如何行通,意义不大),
并且之前类里面的name属性的值会被覆盖掉
类写法:
class Myd(View): name = 'sb' def get(self,request,n): print('get方法执行了') print('>>>',n) return render(request,'cvpost.html',{'name':self.name}) def post(self,request,n): print('post方法被执行了') return HttpResponse('post')
四.给视图加装饰器
使用装饰器装饰FBV
FBV本身就是一个函数,就是Python通用装饰器的加法.
def wrapper(func): def inner(*args,**kwargs): start_time = time.time() ret = func(*args,**kwargs) end_time = time.time() print("used:",end_time - start_time) return ret return inner #FBV版本添加班级 @wrapper def add_class(request): if request.method == "POST": class_name = request.POST.get("calss_name") mo