4、Django的views

Django的視圖相關(views)html

  1. 請求相關的屬性方法(request--HttpRequest對象)

request的方法:django

  • request.method:獲取請求的方式,'GET'、'POST'
  • request.body:獲取post請求提交過來的原始數據,bytes類型,b'username=alex'
  • request.GET:獲取GET請求提交的數據
    request.POST:獲取POST請求提交的數據
    request.GET.get('year')
    request.POST.get('year')
  • request.META:請求頭相關信息,就是一個大字典
  • request.path: 路徑 ,/index/
    request.path_info: 路徑 ,/index/
  • 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

  1. 響應相關的方法
  • HttpResponse --- 回覆字符串的時候來使用
  • render --- 回覆一個html頁面的時候使用
  • redirect -- 重定向
    • 通過操做以後幫助你自動跳轉到別的頁面。好比一個網站,有些功能須要登陸才能訪問,因此在用戶點擊那個功能後,先返回給用戶一個登陸的頁面,在用戶登陸成功以後就自動跳轉到用戶點擊那個功能的那個頁面,不須要用戶登錄成功以後再回去點擊,提升了用戶的體驗
    • 在網站更新時,不維護老網站了,從新開發了一個新網站。當有用戶訪問老網站的時候,就重定向到這個新的網站。
    • 重定向狀態碼301和302的區別:
      • 301:表示舊地址A的資源已經被永久地移除了(這個資源不可訪問了),搜索引擎在抓取新內容的同時也將舊的網址交換爲重定向以後的網址;
      • 302:表示舊地址A的資源還在(仍然能夠訪問),這個重定向只是臨時地從舊地址A跳轉到地址B,搜索引擎會抓取新的內容而保存舊的網址。

示例:用戶訪問網站,讓用戶輸入用戶名、密碼,判斷若是正確,進入到會員頁面網站

  1. urls:
    from django.conf.urls import url
    from app01 import views搜索引擎

    urlpatterns = [
        url(r'^login/', views.login),
    ]
  2. login.html:
    url

    登陸頁面——請登陸會員

    <form action="" method="post">
        用戶名:<input type="text" name="username">
        密碼:<input type="text" name="password">
        <button>提交</button>
    </form>
  3. 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')

    這個時候,登陸成功就跳轉到一個新的網址了

  4. 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是如何經過不一樣的請求方法找到對應的試圖類中的方法?

  • 首先urls.py中,views.MyView.as_view() ,是MyView調用了as_view()這個方法,而MyView是咱們本身建立的類,是沒有as_view()這個方法的,因此class MyView(View),就是繼承的View裏面的as_view()方法
  • 點開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
        請求之完事啦
  1. 加裝飾器

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):
        ...
相關文章
相關標籤/搜索