7.Django之视图函数view
简单的视图函数
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
CBV和FBV
FBV(function base views) 就是在视图里使用函数处理请求.
CBV(class base views) 就是在视图里使用类处理请求。
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
FBV
from django.http import HttpResponse def my_view(request): if request.method == 'GET': return HttpResponse('OK')
CBV
from django.http import HttpResponse def my_view(request): if request.method == 'GET': return HttpResponse('OK')
Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()
静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()
方法,dispatch()
方法会根据request的method的不同调用相应的方法来处理request(如get()
, post()
等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。
from django.conf.urls import url from myapp.views import Cbv #引入我们在views.py里面创建的类 urlpatterns = [ url(r'^cbv/',views.Cbv.as_view(),name='Cbv'), ]
CBV和FBV类似,有名分组,无名分组
url(r'^cv/(\d{2})/', views.Cbv.as_view(),name='cbv'), url(r'^cv/(?P<n>\d{2})/', views.Cbv.as_view(name='xxx'),name='cbv'),
类写法
from django.http import HttpResponse from django.views import View class GreetingView(View): name = "yuan" def get(self, request): return HttpResponse(self.name)
给视图加装饰器
给FBV加装饰器
def warpper(fn): def inner(*args,**kwargs): print("之前") ret = fn(*args,**kwargs) print("之后") return ret return inner @warpper def cbv(request): method = request.method print('函数执行....') if method == 'POST': username = request.POST.get('username') return HttpResponse(username) else: return render(request,'cbv.html')
给CBV加装饰器
from django.views import View from django.utils.decorators import method_decorator @method_decorator(warpper,name='post') class Cbv(View): # @method_decorator(warpper) def dispatch(self, request, *args, **kwargs): print('请求之前') ret = super().dispatch(request, *args, **kwargs) print('请求之后') return ret def get(self,request): print('这是get请求') return render(request,'cbv.html') # @method_decorator(warpper) def post(self,request): print("这个是post请求") username = request.POST.get('username') return HttpResponse(username)