AI-CBV写法
CBV固定样式
#url.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.Loginview.as_view()), #CBV格式,Loginview是类名
]
# views.py
from django.shortcuts import render,HttpResponse
from django.views import View
# Create your views here.
class Loginview(View): #里边可以封装很多方法
def get(self,request):
return render(request,"login.html",locals())
def post(self,request):
return HttpResponse("post")
#login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<form action="" method="post">
{% csrf_token %}
用户名:<input type="text" name="user">
密码:<input type="password" name="pwd">
<button type="submit">提交</button>
</form>
</body>
</html>
CBV源码解析
#1.从url开始执行
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', Views.Loginview.as_view()), #CBV格式,Loginview是类名
]
#2.url(r'^login/', views.Loginview.as_view()) 代表在Loginview继承的View类中找as_view方法
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'): # self,即Login_View对象
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
return view
# 3.调用as_view方法时,返回了view,相当于
url(r'^login/', Views.view)
# 4.一旦用户get访问login,相当于给view传参view(request)
def view(request, *args, **kwargs):
self = cls(**initkwargs) #5.cls为当前类的实例化对象,即LoginView的实例化对象
if hasattr(self, 'get') and not hasattr(self, 'head'): # self,即Login_View对象
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs) #6.表示从LoginView的实例化对象中找dispatch方法
# 7.找不到dispatch方法,就在View中找
class Loginview(View): #里边可以封装很多方法
def get(self,request):
return render(request,"login.html",locals())
# 8. 找到dispatch方法,
class View(object):
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
# handler表示get、post等
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) #8.self不在request.method.lower()中,
# 就使用self.http_method_not_allowed进行报错处理
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) #9.执行handler(get()、post()等方法)
# 10.执行get等方法,返回前端页面,完毕
class Loginview(View): #里边可以封装很多方法
def get(self,request):
return render(request,"login.html",locals())
CBV重写dispatch
# views.py
from django.shortcuts import render,HttpResponse
from django.views import View
# Create your views here.
class Loginview(View): #里边可以封装很多方法
def dispatch(self, request, *args, **kwargs):
print("可以将公共的功能放到此处")
#其实这样写,和没有写dispatch方法功能一样,"多此一举"?不是,有用处滴!
# 每次执行代码都会走这个dispatch方法,可以将公共的功能放到此处
ret=super().dispatch(request,*args,**kwargs) #覆盖源码dispatch功能
return ret
def get(self,request):
return render(request,"login.html",locals())
def post(self,request):
return HttpResponse("post")