Django框架--四--类视图

版权声明:转载请标明出处 https://blog.csdn.net/gymaisyl/article/details/84680254

1.函数视图与类视图的比较

在讲解类视图之前,我们可以先看一下,普通的视图函数在处理请求的时候,是怎样的一种情况:

 def register(request):
    """注册"""

    # 获取请求方法,判断是GET/POST请求
    if request.method == 'GET':
        # 处理GET请求,返回注册页面
        return render(request, 'register.html')
    else:
        # 处理POST请求,实现注册逻辑
        return HttpResponse('这里实现注册逻辑')

如代码所示,针对同一个接口(这里指的是注册),根据不同的请求方式,我们需要进行判断后才能进行对应的处理,代码的可读性和复用性相对来说就比较差;

而在Django中,可以通过类来进行视图你的定义 ,称为类视图,代码如下:

from django.views.generic import View

class RegisterView(View):
    """注册"""

    def get(self, request):
        """处理GET请求,返回注册页面"""
        return render(request, 'register.html')

    def post(self, request):
        """处理POST请求,实现注册逻辑"""
        return HttpResponse('这里实现注册逻辑')

类视图的好处:

  • 代码可读性好
  • 类视图相对于函数视图有更高的复用性, 如果其他地方需要用到某个类视图的某个特定逻辑,直接继承该类视图即可;

2.类视图的使用

定义类视图需要继承自Django提供的父类View,可使用from django.views.generic import View或者from django.views.generic.base import View 导入都可以,实现方式就是类似于上面的代码;

使用类视图的话,在定义路由的时候,就得使用as_view()进行路由的分发了;

urlpatterns = [
    url(r'^register/$', views.RegisterView.as_view(), name='register'),
]

3.类视图原理

源代码参考:

class View(object):
    """
    Intentionally simple parent class for all views. Only implements
    dispatch-by-method and simple sanity checking.
    """

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

    def __init__(self, **kwargs):
        """
        Constructor. Called in the URLconf; can contain helpful extra
        keyword arguments, and other things.
        """
        # Go through keyword arguments, and either save their values to our
        # instance, or raise an error.
        for key, value in six.iteritems(kwargs):
            setattr(self, key, value)

    @classonlymethod
    def as_view(cls, **initkwargs):
        """
        Main entry point for a request-response process.
        """
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))

        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request
            self.args = args
            self.kwargs = kwargs
            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=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())
        return view

    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)

讲解:
在url中,我们是在调用as_view()这个函数,在源代码中我们可以看到,
调用as_view()实际上是给我们返回了view方法:
在这里插入图片描述

那好,我们再进行view方法的调用执行:
view方法执行后,我们可以从源代码中了解到,在Django的视图函数里面,我们是可以获取到请求对象(request),以及请求中的关键字参数(kwargs),当然,最重要的是,我们下一步是执行dispatch()函数
在这里插入图片描述

现在开始执行dispatch函数,其实源代码的注释是说的比较清楚的,我们这个dispatch的作用就是:尝试分发正确合理的请求,如果请求不存在或者不合法,那么机会抛出异常,反之,如果正确的,就会进入到对应的请求函数中。
在这里插入图片描述

总结来说,我们通过使用Django的类视图,在urls中定义路由是通过.as_view()方式进行的,那么他们就已经帮我们进行路由的分发了,针对不同的请求方式,只要我们在视图函数中定义了对应请求的处理方式,那么请求就一定能被处理。

猜你喜欢

转载自blog.csdn.net/gymaisyl/article/details/84680254