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()方法。

在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()方法源码如下:

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请求访问该视图,结果如下:

在这里插入图片描述

始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。
原文地址:https://www.cnblogs.com/guyan-2020/p/12293313.html