Django之FBV / CBV和中間件

FBV / CBV 

FBV:function base viewdjango

 url(r'^index$',user)
路由
def users(request):
    return HttpResponse(‘OK’)
視圖

CBV:class base viewjson

url(r'^students/', views.StudentsView.as_view())
路由
from django.views import View

class StudentsView(View):

    def get(self,request,*args,**kwargs):
    return HttpResponse('GET')

    def post(self, request, *args, **kwargs):
    return HttpResponse('POST')

    def put(self, request, *args, **kwargs):
    return HttpResponse('PUT')

    def delete(self, request, *args, **kwargs):
    return HttpResponse('DELETE')
視圖

CBV實現原理瀏覽器

  基於反射實現根據請求方式不一樣,執行不一樣的方法。具體實現流程:url中的as_view() —》 view方法 —》 dispatch方法(根據反射執行相應函數)session

CBV中可使用的方法:app

 http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
from django.views import View
class RestApi(View):
    def dispatch(self,request,*args,**kwargs):
        func = getattr(self,request.method.lower())
        ret = func(request,*args,**kwargs)
        return ret

    def get(self,request,*args,**kwargs):
        return HttpResponse('get')

    def post(self,request,*args,**kwargs):
        return HttpResponse('post')

    def put(self,request,*args,**kwargs):
        return HttpResponse('put')

    def delete(self,request,*args,**kwargs):
        return HttpResponse('delete')
手動實現dispatch方法
from django.views import View
class RestApi(View):
    def dispatch(self,request,*args,**kwargs):
        ret = super(RestApi, self).dispatch(request,*args,**kwargs)
        return ret

    def get(self,request,*args,**kwargs):
        return HttpResponse('get')

    def post(self,request,*args,**kwargs):
        return HttpResponse('post')

    def put(self,request,*args,**kwargs):
        return HttpResponse('put')

    def delete(self,request,*args,**kwargs):
        return HttpResponse('delete')
手動繼承dispatch方法

Django中間件

  django 中的中間件(middleware),在django中,中間件其實就是一個類,在請求到來和結束後,django會根據本身的規則在合適的時機執行中間件中相應的方法。ide

咱們從瀏覽器發出一個請求 Request,獲得一個響應後的內容 HttpResponse ,這個請求傳遞到 Django的過程以下:函數

  每個請求都是先經過中間件中的 process_request 函數,這個函數返回 None 或者 HttpResponse 對象,若是返回前者,繼續處理其它中間件,若是返回一個 HttpResponse,就處理停止,返回到網頁上。post

中間件中能夠定義4個方法,分別是:url

  1. process_request(self,request) 發送請求
  2. process_view(self, request, callback, callback_args, callback_kwargs) 執行完 request 預處理函數並肯定待執行的 view 以後,但在 view 函數實際執行以前。
  3. process_template_response(self,request,response)
  4. process_exception(self, request, exception) 收集錯誤信息
  5. process_response(self, request, response) 必須返回 HttpResponse 對象. 這個 response 對象能夠是傳入函數的那一個原始對象(一般已被修改),也能夠是全新生成的。

執行順序也是按照以上順序執行的.spa

自定義中間件

from django.utils.deprecation import MiddlewareMixin

class test1(MiddlewareMixin):
    def process_request(self, request):
        print('wusir')

class test2(MiddlewareMixin):
    def process_request(self, request):
        print('jack')
View Code

註冊中間件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'wusir.m1.test1',
    'wusir.m1.test2',
]
View Code

終端輸出結果

wusir
jack
tom
[17/Dec/2018 17:08:04] "GET /app/aa HTTP/1.1" 200 2
View Code

PS:與mange.py在同一目錄下的文件夾 wusir下的m1.py文件中的test1,test2類

中間件能夠作什麼

  •   權限
  •   用戶登陸驗證
  •   Django的csrf的實現
狀況一:
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware', # 全站使用csrf認證
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


from django.views.decorators.csrf import csrf_exempt
@csrf_exempt # 該函數無需認證
def users(request):
    user_list = ['alex','oldboy']
    return HttpResponse(json.dumps((user_list)))

狀況二:
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware', # 全站不使用csrf認證
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


from django.views.decorators.csrf import csrf_exempt
@csrf_protect # 該函數需認證
def users(request):
    user_list = ['alex','oldboy']
    return HttpResponse(json.dumps((user_list)))
爲某個函數單獨增長或取消CSRF認證

CSRF在CBV中的使用補充
  裝飾器@csrf_exempt,@csrf_protect必須在dispatch方法中(單獨方法無效)

方式一:
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    from django.utils.decorators import method_decorator
    class StudentsView(View):
        
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            return super(StudentsView,self).dispatch(request, *args, **kwargs)

        def get(self,request,*args,**kwargs):
            print('get方法')
            return HttpResponse('GET')

        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')

        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')

        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')
方式二:
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    from django.utils.decorators import method_decorator

    @method_decorator(csrf_exempt,name='dispatch')
    class StudentsView(View):

        def get(self,request,*args,**kwargs):
            print('get方法')
            return HttpResponse('GET')

        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')

        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')

        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')
View Code
相關文章
相關標籤/搜索