类视图:
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())