Django的視圖相關(views)html
request的方法:django
request.get_full_path():get請求的ip和端口後面的全部,即:路徑+數據,/index/?username=dazhuang&password=123app
from django.shortcuts import render,HttpResponse函數
def index(request):
if request.method == 'GET':
print(request.body) # b''
print(request.GET) # <QueryDict: {'year': ['2018'], 'month': ['12']}>
print(request.GET.get('year')) # 2018
print(request.META) # 請求頭相關信息,就是一個大字典
print(request.path) # /index/ 路徑
print(request.path_info) # /index/ 路徑
print(request.get_full_path()) # /index/?year=2018&month=12
return render(request,'index.html')
else:
print(request.body) # b'year=2018&month=12'
print(request.POST) # <QueryDict: {'year': ['2018'], 'month': ['12']}>
print(request.POST.get('year')) # 2018
return HttpResponse('查詢了哈哈~~')post
示例:用戶訪問網站,讓用戶輸入用戶名、密碼,判斷若是正確,進入到會員頁面網站
urls:
from django.conf.urls import url
from app01 import views搜索引擎
urlpatterns = [ url(r'^login/', views.login), ]
login.html:
url
<form action="" method="post"> 用戶名:<input type="text" name="username"> 密碼:<input type="text" name="password"> <button>提交</button> </form>
views
from django.shortcuts import render,HttpResponsespa
def login(request): if request.method == 'GET': return render(request,'login.html') else: username = request.POST.get('username') password = request.POST.get('password') if username == 'yangzm' and password == '17130': return render(request,'member.html') else: return HttpResponse('您不是咱們的用戶')
這個方法沒有用重定向,也完成了相關的功能,可是會發現,此時的域名仍是 login/,這樣是不合適的,不能仍是原來的地址,須要跳轉到一個新的網頁地址code
改進的views:
urls.py文件裏面添加一個member的路徑
urlpatterns = [
url(r'^login/', views.login),
url(r'^member/', views.member),
]
from django.shortcuts import render,HttpResponse def login(request): if request.method == 'GET': return render(request,'login.html') else: username = request.POST.get('username') password = request.POST.get('password') if username == 'yangzm' and password == '17130': # return render(request,'member.html') return redirect('/member/') else: return HttpResponse('您不是咱們的用戶') def member(request): return render(request, 'member.html')
這個時候,登陸成功就跳轉到一個新的網址了
FBV和CBV
FBV(function base views) 就是在視圖裏使用函數處理請求。
CBV(class base views) 就是在視圖裏使用類處理請求。
好比處理一個GET方法的views,用函數寫:
FBV from django.http import HttpResponse def my_view(request): if request.method == 'GET': return HttpResponse('OK')
而後用類的方法來寫:
CBV views.py: from django.http import HttpResponse from django.views import View # 須要導入View class MyView(View): # 經過請求方法找到本身寫的視圖類裏面對應的方法 def get(self, request): # 必須寫的get,要和請求'GET'對應 return HttpResponse('OK') urls.py url(r'^myview/', views.MyView.as_view()),
CBV是如何經過不一樣的請求方法找到對應的試圖類中的方法?
點開View的源碼:關鍵點——反射
class View(object):
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
......
def as_view(cls, initkwargs):
......
def view(request, args, kwargs):
self = cls(initkwargs)
......
return self.dispatch(request, args, kwargs) # 主要方法
return view def dispatch(self, request, *args, **kwargs): if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) # 經過反射去調用相對應的方法 else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
as_view()靜態方法(也就是類方法),調用這個方法,會建立一個類的實例,而後經過實例調用dispatch()方法,dispatch()方法會根據request的method的不一樣調用相應的方法來處理request(如get(),post()等)
CBV的dispatch方法
# 經過重寫dispatch方法,能夠在執行請求(get,post等)以前以後作一些拓展 class MyView(View): 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,'login.html') def post(self,request): username = request.POST.get('uname') password = request.POST.get('pwd') print(username,password) return HttpResponse('登陸成功!') # 結果: # 在訪問頁面時,get請求執行: 請求以前的內容~~~~~ get方法執行了 請求之完事啦 # 在input框輸入用戶名密碼,提交,發送的post請求執行: 請求以前的內容~~~~~ yangzm 123 請求之完事啦
FBV加裝飾器
# 就是正常寫個裝飾器,而後用語法糖就行 def warpper(f): def inner(*args,**kwargs): print('請求以前') ret = f(*args,**kwargs) print('請求以後') return ret return inner @warpper def my_view(request): if request.method == 'GET': return HttpResponse('OK')
CBV加裝飾器
# 先導入 method_decorator # 有三種方法: # 方式一: @method_decorator(warpper) # 給某個請求添加裝飾器 def get(self,request): pass # 方式二: @method_decorator(warpper) # 給全部方法加裝飾器 def dispatch(self,request, *args, **kwargs): pass # 方式三: @method_decorator(warpper,name='get') # 給某個方法加裝飾器 class MyView(View): pass from django.views import View from django.utils.decorators import method_decorator # Django提供的裝飾器 def warpper(f): def inner(*args,**kwargs): print('請求以前') ret = f(*args,**kwargs) print('請求以後') return ret return inner @method_decorator(warpper,name='get') # 方式三:只給get請求加 class MyView(View): @method_decorator(warpper) # 方式二:給全部請求加 def dispatch(self, request, *args, **kwargs): print('請求以前的內容~~~~~') ret = super().dispatch(request,*args, **kwargs) print('請求之完事啦') return ret @method_decorator(warpper) # 方式一:只給get請求加 def get(self,request): print('get方法執行了') return render(request,'login.html') def post(self,request): username = request.POST.get('uname') password = request.POST.get('pwd') print(username,password) return HttpResponse('登陸成功!')
5.簡單總結
請求相關request
request.method 請求方法 request.body post請求原始數據 request.POST request.GET request.path 獲取路徑 request.path_info request.get_full_path() 獲取路徑及參數 request.META 請求頭相關信息
響應相關
HttpResponse render redirect
FBV和CBV
def index(request): return render(request,'xx.html') from django.views import View class Index(View): def dispatch(self,request,*args,**kwargs): 請求前乾點兒事 ret = super().dispatch(request,*args,**kwargs) 請求後乾點兒事兒 return ret def get(self,request): ... def post(self,request): ...
裝飾器
def wrapper(f): def inner(*args,**kwargs): 前戲 ret = f(*args,**kwargs) 收工 return ret return inner @wrapper def index(request): return render(request,'xx.html') from django.utils.decorators import method_decorator @method_decorator(wrapper,name='get') class Index(View): @method_decorator(wrapper) def dispatch(self,request,*args,**kwargs): 請求前乾點兒事 ret = super().dispatch(request,*args,**kwargs) 請求後乾點兒事兒 return ret @method_decorator(wrapper) def get(self,request): ... def post(self,request): ...