CBV與FBV

FBV

FBV(function base views)就是在 url 中一個路徑對應一個函數html

urls.pypython

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index)
]

views.pydjango

def index(request):
    return render(request, 'index.html')

CBV

CBV(class base views) 就是在視圖裏使用類處理請求,它是基於反射實現,根據請求的方式不一樣,去執行不一樣的方法json

流程:路由 --- View函數 --- dispatch執行反射cookie

urls.pysession

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^students/', views.StudentsView.as_view()),
]

views.pyapp

from django.views import View

class StudentsView(View): 

    def dispatch(self, request, *args, **kwargs):
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        return ret

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

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

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

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

請求進來,先執行這個 dispatch() ,而後調用父類 Viewdispatch()函數

# View 的 dispatch()

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    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)

第一個參數 selfStudentsView 的對象,而後執行 getattr,返回 handler(request, *args, **kwargs),至關於找到了 StudentsView 寫的 get 方法,執行返回結果 HttpResponse('GET') ,將這個結果交給 ret , ret 再返回給用戶,因此看到的就是 GETpost

補充

django中間件的幾個方法

  • process_request
  • process_view
  • process_template_response
  • process_exception
  • process_response

django的csrf_token是如何實現的

  • process_view方法實現,檢查視圖函數是否被 @csrf_exempt,用來免除 csrf 認證
  • 去請求體或 cookie 中獲取 token

FBV知識點:給視圖函數添加裝飾器

狀況一

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_protect

@csrf_protect   # 該函數須要認證
def users(request):
    user_list = ['alex', 'oldboy']
    return HttpResponse(json.dumps(user_list))

CBV知識點:給視圖類添加裝飾器

沒法給單獨的函數添加裝飾器,必須加到 dispatch() 上,或者在類上加裝飾器url

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',
]

方式一:dispatch() 加裝飾器

from django.shortcuts import HttpResponse
from django.views import View
from django.utils.decorators import method_decorator

class StudentsView(View): 
    
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        ret = super(StudentsView, self).dispatch(request, *args, **kwargs)
        return ret

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

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

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

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

方式二:類加裝飾器

from django.shortcuts import HttpResponse
from django.views import View
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch') # name表示只給dispatch加裝飾器
class StudentsView(View): 
    
    def get(self, *args, **kwargs):
        return HttpResponse('GET')

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

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

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

總結

  • CBV 定義類的時候必需要繼承 View
  • 在寫 url 的時候必需要加 as_view()
  • 全部的方法本質上都是經過 dispatch 這個函數反射執行,若是想要在執行 getpost 方法前執行其餘步驟,能夠重寫 dispatch
  • 添加裝飾器前必須導入from django.utils.decorators import method_decorator
  • 添加裝飾器的格式必須爲 @method_decorator(),括號裏面爲裝飾器的函數名
  • 給類添加是必須聲明 name
  • 注意 csrf-token 裝飾器的特殊性,它只能加在 dispatch 上面
相關文章
相關標籤/搜索