按Django官方的说法,在Django开发过程中我们可以使用function-base-view(函数视图)和clase-base-view(类视图)实现http请求的相关处理。函数视图和类视图没有优劣的区分,各有好处。
函数视图处理http请求的时可以直接调用request.method属性进行判断http请求的类型,如:
from django.http import HttpResponse
def my_view(request):
if request.method == 'GET':
#
return HttpResponse('result')
使用类视图时实现http请求处理时可以将每种请求写成类的方法,便于扩展,如对继承自基本类View,编写get()方法,当HTTP发起get()请求时会自动匹配到这个自定义的get()方法。
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request):
#
return HttpResponse('result')
首先在view.generic.base.py中可以找到所有已定义的http请求类型:
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
当HTTP发起请求时,通过类视图的as_view()方法传入请求类型,as_view()就根据上面定义的方法进行遍历找到。具体地在as_view(),又分别调用setup()和dispatch()方法,其中dispatch()方法就是通过python类的内置函数getattr()方法查找当前扩展类中是否有类方法与HTTP请求匹配,如上面例子中的get()处理方法。当查找到相应的方法后as_view()就会返回这个自定义方法的结果:
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
def setup(self, request, *args, **kwargs):
"""Initialize attributes shared by all view methods."""
self.request = request
self.args = args
self.kwargs = kwargs
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)
这样在Django开发过程中,当使用到类视图如View, ListView, DetailView, TemplateView时可以通过编写类方法的方式自定义get, post等请求的处理,在后续开发中可以灵活地重写这些方法,以达到需求。