FBV
fbv就是在url中一個路徑對應(yīng)一個函數(shù)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index)
]
在視圖函數(shù)中
def index(request):
return render(request, 'index.html')
CBV
cbv就是在url中一個路徑對應(yīng)一個類
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.IndexView.as_view()) # 執(zhí)行類后面的as_view()方法,是父類里面的方法
]
在視圖函數(shù)中
from django.views import View
class IndexView(View):
# 以get形式訪問會執(zhí)行g(shù)et函數(shù),一般情況下獲取數(shù)據(jù)
def get(self, *args, **kwargs):
return HttpResponse('666')
# 以post形式訪問的話會執(zhí)行post函數(shù),一般情況下發(fā)送數(shù)據(jù)
def post(self, *args, **kwargs):
return HttpResponse('999')
注意:
- cbv定義類的時候必須要繼承view
- 在寫url的時候必須要加as_view
- 類里面使用form表單提交的話只有g(shù)et和post方法
- 類里面使用ajax發(fā)送數(shù)據(jù)的話支持定義以下很多方法
restful規(guī)范:
'get'獲取數(shù)據(jù), 'post'創(chuàng)建新數(shù)據(jù), 'put'更新, 'patch'局部更新, 'delete'刪除, 'head', 'options', 'trace'
CBV重新定義dispatch函數(shù)
所有的方法本質(zhì)上都是通過dispatch這個函數(shù)反射執(zhí)行,如果想要在執(zhí)行g(shù)et或post方法前執(zhí)行其他步驟,可以重寫dispatch
class IndexView(View):
# 重寫父類的dispatch方法,如果不重寫,他會執(zhí)行父類的dispatch方法,
def dispatch(self, request, *args, **kwargs):
print('before')
res = super(IndexView, self).dispatch(request, *args, **kwargs)
print('after')
return res
# 以get形式訪問會執(zhí)行g(shù)et函數(shù)
def get(self, *args, **kwargs):
return HttpResponse('666')
# 以post形式訪問的話會執(zhí)行post函數(shù)
def post(self, *args, **kwargs):
return HttpResponse('999')
下面我們根據(jù)上面的寫法添加用戶登錄驗證
from django.shortcuts import render, HttpResponse, redirect
from django.views import View
class LoginView(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'rdw' and pwd == '666':
request.session['user_info'] = 'rdw'
return redirect('/index/')
else:
return render(request, 'login.html')
class IndexView(View):
# 重寫父類的dispatch方法,如果不重寫,他會執(zhí)行父類的dispatch方法,
def dispatch(self, request, *args, **kwargs):
if not request.session.get('user_info'):
return redirect('/login/')
res = super(IndexView, self).dispatch(request, *args, **kwargs)
return res
# 以get形式訪問會執(zhí)行g(shù)et函數(shù)
def get(self, request, *args, **kwargs):
return render(request, 'index.html')
# 以post形式訪問的話會執(zhí)行post函數(shù)
def post(self, *args, **kwargs):
return HttpResponse('999')
給視圖類添加裝飾器
如果有多個程序需要用戶登錄驗證的話會造成代碼冗余,可以使用繼承很好的解決這個問題,但是還有更好的方法,那就是基于裝飾器實現(xiàn)登錄驗證
定義裝飾器
def login_test(func):
def inner(request, *args, **kwargs):
if not request.session.get('user_info'):
return redirect('/login/')
return func(*args, **kwargs)
return inner
-
直接添加在dispatch里面,這樣每個函數(shù)都會執(zhí)行
from django.utils.decorators import method_decorator
@method_decorator(login_test)
def dispatch(self, request, *args, **kwargs):
res = super(IndexView, self).dispatch(request, *args, **kwargs)
return res -
添加在每一個函數(shù)中
from django.utils.decorators import method_decorator
@method_decorator(login_test)
def get(self, request, *args, **kwargs):
return render(request, 'index.html') -
直接添加在類上,后面的name表示只給get添加裝飾器
from django.utils.decorators import method_decorator
@method_decorator(login_test, name='get')
class IndexView(View):
注意:
- 添加裝飾器前必須導(dǎo)入from django.utils.decorators import method_decorator
- 添加裝飾器的格式必須為@method_decorator(),括號里面為裝飾器的函數(shù)名
- 給類添加是必須聲明name
- 注意csrf-token裝飾器的特殊性,它只能加在dispatch上面