110.類視圖詳解

類視圖:

1. 定義視圖函數只能使用get方法進行訪問,若是出現了沒有定義的方法,那麼就將這個請求轉換爲http_method_not_allowed(request, *args, **kwargs)。
views.py文件中示例代碼以下:

from django.views.generic.base import View


# 實現:定義該視圖只支持get請求
class BookAddView(View):
    def get(self, request, *args, **kwargs):
        return render(request, 'book/static/bookview.html')

    def http_method_not_allowed(self, request, *args, **kwargs):
         return HttpResponse('您當前的請求方式爲%s,該視圖的請求方式只能爲GET。' % request.method)
         
    # 同時,也能夠定義返回的狀態碼
        # response = HttpResponse(status=404)
        # context = '請求方式只能爲GET'
        # response.content = context
        # return response

==注意:這裏定義的類必定要繼承View,若是沒有繼承的話,在urls.py文件中進行映射的時候就不能轉換爲類視圖,即不能調用as_view()方法。==html

在urls.py文件中進行映射,示例代碼以下:
from django.urls import path
from . import views

urlpatterns = [
    path('bookview/', views.BookView.as_view(), name='bookview'),
    path('book_add/', views.BookAddView.as_view(), name='book_add'),
]

2.定義類視圖能夠處理多種請求,views.py文件中,示例代碼以下:

# 實現:在瀏覽器發送過來的請求爲GET請求的時候,返回一個添加圖書信息的頁面
# 在瀏覽器發送過來的請求爲POST時,就將數據提取出來進行打印。
class BookView(View):
    def get(self, request, *args, **kwargs):
        return render(request, 'book/static/bookview.html')

    def post(self, request, *args, **kwargs):
        name = request.POST.get('name')
        author = request.POST.get('author')
        print("書名:{},做者:{}".format(name, author))
        return HttpResponse('success!')

3.須要注意的是,在調用類視圖時,無論你是使用GET請求,仍是POST請求,都不會先去執行這些請求的方法,而是首先調用類視圖的dispatch(request, args, kwargs)方法,將請求的方式轉換爲小寫形式,以後判斷這種請求的方式是否在定義的各類請求方式之中,若是在的話,就會執行類視圖中定義的相應的請求方法。

==其中,django定義View類中的dispatch()方法源碼以下:==python

class View:

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    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)
        
    def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning(
            'Method Not Allowed (%s): %s', request.method, request.path,
            extra={'status_code': 405, 'request': request}
        )
        return HttpResponseNotAllowed(self._allowed_methods())
4.將以上代碼擴充一下:
class HttpResponseNotAllowed(HttpResponse):
    status_code = 405

    def __init__(self, permitted_methods, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['Allow'] = ', '.join(permitted_methods)

    def __repr__(self):
        return '<%(cls)s [%(methods)s] status_code=%(status_code)d%(content_type)s>' % {
            'cls': self.__class__.__name__,
            'status_code': self.status_code,
            'content_type': self._content_type_for_repr,
            'methods': self['Allow'],
        }


class BookDetailView(View):

    http_method_names = ['get', 'post']

    def get(self, request, *args, **kwargs):
        return render(request, 'book/static/bookview.html')

    def post(self, request, *args, **kwargs):
        name = request.POST.get('name')
        author = request.POST.get('author')
        print("name:{},author:{}".format(name, author))
        return HttpResponse('success')

    def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning(
            "Method Not Allowed (%s):%s",request.method,request.path,
            extra={'status_code':405, 'request':request}
        )
        return HttpResponseNotAllowed(self._allowed_methods())
在Postman中使用put請求訪問該視圖,結果以下:

在這裏插入圖片描述

相關文章
相關標籤/搜索