Django中url中可以使用类视图.as_view()进行映射的原因

说明:本人在学练习天天生鲜项目时,对利用类视图去与正则匹配到的url做映射有点疑惑,经过查看他人博客以及自我分析算是整明白了,所以记录一下

参考:https://www.zmrenwu.com/post/53/

HTTP发送请求的方式有很多种,这里以POST,GET为例。当在浏览器中输入url地址时(如http://127.0.0.1:8000/userr/register)

会进行正则匹配,并映射到ActiveView.as_view(),其最终达到能将注册页面显示出来的效果,原因如下:

class RegisterView(View):
    ‘‘‘注册‘‘‘
    def get(self, request):
        ‘‘‘显示注册页面‘‘‘
        return render(request, ‘register.html‘)

    def post(self, request):
        ‘‘‘进行注册处理‘‘‘
        ‘‘‘进行注册处理‘‘‘
        # 接收数据
        username = request.POST.get(‘user_name‘)
        password = request.POST.get(‘pwd‘)
        email = request.POST.get(‘email‘)
        allow = request.POST.get(‘allow‘)
        # 进行数据处理
        if not all([username, password, email]):
            return render(request, ‘register.html‘, {‘errmsg‘: ‘数据不完整‘})
        # 校验邮箱
        if not re.match(r‘^[a-z0-9][\w.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$‘, email):
            return render(request, ‘register.html‘, {‘errmsg‘: ‘邮箱格式不正确‘})

        # 校验协议
        if allow != ‘on‘:
            return render(request, ‘register.html‘, {‘errmsg‘: ‘请同意协议‘})
        # 校验用户名是否重复
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # 用户不存在
            user = None

        # 进行业务处理: 进行用户注册
        user = User.objects.create_user(username, email, password)
        user.is_active = 0
        user.save()

        # 发送激活邮件
        serializer = Serializer(settings.SECRET_KEY, 3600)
        info = {‘confirm‘:user.id}
        token = serializer.dumps(info) # bytes
        token = token.decode()
        # 发邮箱
        send_register_active_email.delay(email, username, token)
        # subject = ‘天天生鲜欢迎信息‘
        # message = ‘‘
        # sender = settings.EMAIL_FROM
        # receiver = [email]
        # html_message = ‘<h1>%s, 欢迎您成为天天生鲜注册会员</h1>请点击下面链接激活您的账户<br/><a href="http://127.0.0.1:8000/userr/active/%s">http://127.0.0.1:8000/userr/active/%s</a>‘ % (
        #     username, token, token)
        # send_mail(subject, message, sender, receiver, html_message=html_message)
        # 返回应答,跳转到首页
        return redirect(reverse(‘goods:index‘))

  

RegisterView类中并没有as_view()方法,但其父类View中有as_view()方法,所以父类的此方法就被调用,父类View原码如下

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)

    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 http.HttpResponseNotAllowed(self._allowed_methods())

    def options(self, request, *args, **kwargs):
        """
        Handles responding to requests for the OPTIONS HTTP verb.
        """
        response = http.HttpResponse()
        response[‘Allow‘] = ‘, ‘.join(self._allowed_methods())
        response[‘Content-Length‘] = ‘0‘
        return response

    def _allowed_methods(self):
        return [m.upper() for m in self.http_method_names if hasattr(self, m)]

dispatch()方法实现的功能如下:

首先它通过 request.method (即 HTTP 请求的方法)判断请求的方法是否是被 HTTP 协议所允许的。如果不合法,就会调用错误处理函数 self.http_method_not_allowed;如果请求方法是合法的,就会试图根据 request.method 去类中寻到对应的处理方法,如果找不到则还是委托给 self.http_method_not_allowed 处理。

代码实现过程:

当在浏览器中输入url地址时(如http://127.0.0.1:8000/userr/register),经过正则匹配以及映射关系,首先调用View.as_view()方法,接着调用as_view()方法中的view()方法,view()方法进一步调用View类内的dispatch()方法。,在dispatch()方法中,request.method判断出HTTP请求的方法为GET,request.method.lower()将GET转换为get,getattr方法将得到的get负值给handler,然后通过return handler()调用handler()方法,即为RegisterView类中的get()方法,而get()方法会返回模板中的html文件(即register.html)。其返回的结果依次return给方法的调用者,最终返回给View.as_view()方法的结果是模板中的register.html文件,即能显示出注册页面,如下

当点击注册时(填好相关信息),此时HTTP的请求方式变成POST,同理,最终也能显示出相应的页面(此处为显示首页)

原文地址:https://www.cnblogs.com/jj1106/p/10995309.html

时间: 2024-11-09 11:48:57

Django中url中可以使用类视图.as_view()进行映射的原因的相关文章

六、Django之表单和类视图-Part 4

一.表单form 为了接收用户的投票选择,我们需要在前端页面显示一个投票界面.让我们重写先前的polls/detail.html文件,代码如下: <h1>{{ question.question_text }}</h1> {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} <form action="{% url 'p

Django框架的使用教程--类视图-中间间-模板[六]

类视图 类视图的使用 视图函数 class class_view(View): """类视图""" def get(self, request): return render(request, 'index.html') def post(self, request): return render(request, 'show.html') 路由 url(r'^class_view/$', views.class_view.as_view()),

Django 官方推荐的姿势:类视图

作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 在开发网站的过程中,有一些视图函数虽然处理的对象不同,但是其大致的代码逻辑是一样的.比如一个博客和一个论坛,通常其首页都是展示一系列的文章列表或者帖子列表.对处理首页的视图函数来说,虽然其处理的对象一个是文章,另一个是帖子,但是其处理的过程是非常类似的:首先是从数据库取出文章或者帖子列表,然后将这些数据传递给模板并渲染模板.于是,django 把这些相同的逻辑代码抽取了出来,写成了

在DJANGO的类视图中实现登陆要求和权限保护

以前接触的是基于函数的保护,网上材料比较多. 但基于类视图的很少. 补上! Decorating class-based views 装饰类视图 对于类视图的扩展并不局限于使用mixin.你也可以使用装饰器. Decorating in URLconf URLconf中的装饰器 最简单的装饰类视图的方式是装饰 as_view() 方法返回的结果.最容易装饰的地方是你配置你的视图的地方URLconf中: from django.contrib.auth.decorators import logi

Django内置auth模块中login_required装饰器用于类视图的优雅方式

使用多继承 以及类似java中的静态代理模式 原理:OrderView.as_view()根据广度优先,调用的是LoginRequiredMixin中的as_view(cls, *args, **kwargs) 这时的cls=OrderView 接下来super(LoginRequiredMixin, cls).as_view(*args, **kwargs) 会调用到View类中的as_view()并返回一个视图函数 然后,用将这个视图函数作为参数传给Login_required()并返回经过

Django中url使用命名空间的错误

出的错误: 1. Reverse for 'llist' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [] 2. Reverse for 'home' with arguments '(1L,)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'org/home/?P<org_id>(/d+)/$'] 出错原因

Django中url的逆向解析 -&gt; Reverse resolution of URLs

之前的一篇文章中介绍了url的基本用法[Django的url用法] 解析的过程可以概括为URL request -> view calling 同时,django又提供了另一种解析方式 - Reverse resolution of URLs 它的解析过程为 view calling -> URL request 因为Django奉行的是DRY原则,所以使用这种方式,就无需对url地址进行硬编码.在原本需要硬编码url的地方,直接可以使用url的名字,然后逆向解析出url地址. Django提

django中url,静态文件,POST请求的配置

平时使用的是pycharm,所以这篇文章主要也是使用pycharm默认创建的django项目为基础进行讲解.项目目录如下图: 1.URL的配置 当创建好项目后,运行项目就可以看到django默认的页面.那么怎么访问自己创建的页面呢? 因为django是类MVC的开发模式.这里面就涉及到配置URL的问题.创建一个自己的APP(也可以称为一个模块),包含的文件内容如下图: 然后需要在setting.py的文件INSTALLED_APPS中注册新创建的App: 新创建项目的默认url配置如下: fro

django中url路由配置及渲染方式

今天我们学习如何配置url.如何传参.如何命名.以及渲染的方式,内容大致有以下几个方面. 创建视图函数并访问 创建app django中url规则 捕获参数 路径转换器 正则表达式 额外参数 渲染方式 创建视图并访问 项目中自带的Python文件中,并没有带有视图,因此我们自己创建一个,通常,我们把视图命名views.py. 然后在views.py中,导入头文件  from django.http import HttpResponse 然后我们在views.py中,写一些Python函数,用来