• Django WSGI,MVC,MTV,中间件部分,Form初识


    一、什么是WSGI?

    WEB框架的本质是一个socket服务端接收用户请求,加工数据返回给客户端(Django),但是Django没有自带socket需要使用 别人的 socket配合Django才能正常运行,socket有很多如下,  但是它们必须遵循一个规范 WSGI(web服务网关接口)这个所有socket都遵守的规范就是WSGI。

    Django默认使用: wsgiref socket(并发性能低 测试使用)

    在公司生产系统上一般用uwsgi+nginx+Django结合使用

    wsgiref +Django工作流程

    1.socket 接受客户端请求 做http请求解析(分割请求头请求体)

    2.wsgiref 把解析之后请求相关信息转发 给 Django

    3.Django框架开始从:中间件-->路由系统(url)-->视图函数(views)、ORM操作(操作数据库,增删改查)、模板渲染(前端输入数据)最终return字符串给socket

    4.socket send (Django产出的字符串),返回客户端

    Wsgi+Django
                from wsgiref.simple_server import make_server
                 
                 
                def RunServer(environ, start_response):
    
                    Django框架开始
                    中间件
                    路由系统
                    视图函数
                    。。。。。
                    
                    start_response('200 OK', [('Content-Type', 'text/html')])
                    
                    
                    return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]
                 
                 
                if __name__ == '__main__':
                    httpd = make_server('127.0.0.1', 8000, RunServer)
                    httpd.serve_forever()
    View Code

    二、MVC/MTV是什么?

    是不有人经常在你面前 装B的提起 MVC 和MTV?

    说白了就是做功能模块的划分,把不同的代码放到不同的文件。

    MVC

    models(数据库,模型)

    views(html模板)

    controllers(业务逻辑处理,函数) --> MVC

    MTV

    models(数据库,模型)

    templates(html模板)

    views(业务逻辑处理函数) --> MTV (Django属于 MTV)

     中间件:

    http请求周期:
    用户在浏览器输入url,在路由系统进行匹配,然后找到视图函数,
    然后取数据,拿模板渲染,把字符串返回给用户

    url----->中间件(管道)---->路由系统(url匹配)-->找到视图函数,取数据,拿模板渲染,给用户返回一个大的字符串

    url------>中间件(class->class->class->class...)----->/login---------->def login(request)
    中间件是由几个类组成,经过类的方法

    MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    用户发请求,发给中间件middleware.security.SecurityMiddleware的方法1,再依次经过各个中间件的方法1,
    再发到视图函数,视图函数的返回值(return HttpResponse() render(),redirect() ) 
    把返回值按照各个中间件的方法2返回给用户
    
    csrf:{%  csrf_token  %}
    
    黑名单(ip1,ip2,ip3,ip4,ip5,ip6......)
    def process_request(self, request)
    def process_response(self, request, response)
    
    请求这里不能有return返回值,响应这里必须有返回值
    
    from django.utils.deprecation import MiddlewareMixin
    
    class Midlle1(MiddlewareMixin):
        def process_request(self, request):
            print('m1.process_request')
            # return request 可以不写,Django会自动传递
            如果请求写返回值,不会继续往下走,会提前结束
        def process_response(self, request, response):
            print('m1.process_response')
            return response
            
    class Midlle1(MiddlewareMixin):
        def process_request(self, request):
            print('m1.process_request')
            # return request 可以不写,Django会自动传递
            # return HttpResponse('不要再往下走了')
        def process_response(self, request, response):
            print('m1.process_response')
            return response
    
    class Midlle2(MiddlewareMixin):
        def process_request(self, request):
            print('m2.process_request')
            # return request 可以不写,Django会自动传递
            # return HttpResponse('不要再往下走了')
        def process_response(self, request, response):
            print('m2.process_response')
            return response
    自定义中间件

    Django 1.10版本之后,遇到return就返回,如果到了公司,有时候会遇到Django1.7或者1.8,遇到return 会找到最后的中间件的response,才返回

    from django.utils.deprecation import MiddlewareMixin
    class M1(MiddlewareMixin):
        def process_request(self,request):
            print('m1.process_request')
    
        def process_view(self, request, callback, callback_args, callback_kwargs):
            print('m1.process_view')
    
        def process_response(self,request,response):
            print('m1.process_response')
            return response
    
    class M2(MiddlewareMixin):
        def process_request(self, request):
            print('m2.process_request')
    
        def process_view(self, request, callback, callback_args, callback_kwargs):
            print('m2.process_view')
    
        def process_response(self, request, response):
            print('m2.process_response')
            return response
    
    '''
    m1.process_request
    m2.process_request
    m1.process_view
    m2.process_view
    test
    m2.process_response
    m1.process_response
    '''
    md.py
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^test/', views.test),
        url(r'^login/', views.login),
    ]
    urls.py
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'md.M1',
        'md.M2',
    ]
    中间件注册

    终极版:

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse,redirect,render
    class M1(MiddlewareMixin):
        def process_request(self,request):
            print('m1.process_request')
    
        def process_view(self, request, callback, callback_args, callback_kwargs):
            # print(callback, callback_args, callback_kwargs)#路由匹配<function test at 0x000000BC53849A60> () {}
            print('m1.process_view')
            # response = callback(request,*callback_args,**callback_kwargs)
            # return response
    
        def process_response(self,request,response):
            print('m1.process_response')
            return response
    
        def process_exception(self,request,exception):
            print('m1.process_exception')
    
        def process_template_response(self,request,response):
            print('m1.process_template_response')
            return response
    class M2(MiddlewareMixin):
        def process_request(self, request):
            print('m2.process_request')
    #view_func视图函数:callback
        def process_view(self, request, callback, callback_args, callback_kwargs):
            # print(callback,callback_args,callback_kwargs)#<function test at 0x0000001B0F2E9A60> () {}
            print('m2.process_view')
            # response = callback(request,*callback_args,**callback_kwargs)
            # return response
        def process_response(self, request, response):
            print('m2.process_response')
            return response
        def process_exception(self,request,exception):
            print('m2.process_exception')
            return HttpResponse('错误了......')
    
        def process_template_response(self,request,response):
            print('m2.process_template_response')
            return response
        """
        视图函数的返回值中,如果有render方法,才会被调用执行
        """
    '''
    m1.process_request
    m2.process_request
    m1.process_view
    test
    m2.process_response
    m1.process_response
    '''
    
    '''
    m1.process_request
    m2.process_request
    m1.process_view
    m2.process_view
    test
    m2.process_response
    m1.process_response
    '''
    #五种中间件:最常用的是:process_request和process_response
    # process_request(self,request)
    # process_view(self, request, callback, callback_args, callback_kwargs)
    # process_template_response(self,request,response)
    # process_exception(self, request, exception)
    # process_response(self, request, response)
    md.py
    class Foo:
        def __init__(self,req,status,msg):
            self.req = req
            self.status = status
            self.msg = msg
        def render(self):
            ret = {
                'status':self.status,
                'msg':self.msg
            }
            return HttpResponse(json.dumps(ret))#返回一个字符串
    
    def test(request):
        # obj = Foo(request)
        return Foo(request,True,"错误信息")
        # print('test')
        # # int('asdf')
        # return HttpResponse('ok')
    """
    视图函数的返回值中,如果有render方法,才会被调用执行
    """
    '''
    m1.process_request
    m2.process_request
    m1.process_view
    m2.process_view
    test
    m2.process_exception
    m1.process_exception
    
    m2.process_response
    m1.process_response
    
    '''
    views.py
    m1.process_request
    m2.process_request
    <function test at 0x000000BC53849A60> () {}
    m1.process_view
    <function test at 0x000000BC53849A60> () {}
    m2.process_view
    test
    m2.process_response
    m1.process_response        
    process_request有返回值和    process_view有返回值的情况不一样
    process_request有返回值时,找到自己的response,自动返回,
    process_view有返回值时,会把所有的中间件的response都执行一遍再返回
    process_exception 遇到views.py中出现异常时输出,程序正确时不会打印m1.process_exception
    ajax请求提交时,返回一个ret,还有一个json.dumps

    中间件使用

    缓存(memcache,redis) 去内存拿数据比硬盘快,请求来时,
    先在缓存取,返回给用户,HTTP请求发来时,要对所有请求做一下判断,才用到中间件

    - 应用:对所有请求或一部分请求做批量处理

    Form表单初识

    Form验证:

    就是对客户端在form表单中输入的数据,进行正确性验证,验证通过再做ORM操作,验证失败抛出提示信息。

    基本使用

    from django.shortcuts import render,redirect,HttpResponse
    from app01 import models
    from django.forms import Form
    from django.forms import fields
    import json
    # Create your views here.
    class JSONResponse:
        def __init__(self,req,status,msg):
            self.req = req
            self.status = status
            self.msg = msg
        def render(self):
            ret = {
                'status':self.status,
                'msg':self.msg
            }
            return HttpResponse(json.dumps(ret))#返回一个字符串
    
    def test(request):
        # obj = Foo(request)
        return JSONResponse(request,True,"错误信息")    #{"status": true, "msg": "u9519u8befu4fe1u606f"}
        # print('test')
        # # int('asdf')
        # return HttpResponse('ok')
    
    class LoginForm(Form):
        # username = fields.CharField(max_lengtj=18,min_length=16, required=True)
        #正则验证:不能为空,6-18位
        username = fields.CharField(
            max_length=18,
            min_length=6,
            required=True,#不能为空
            error_messages={
                'required':'用户名不能为空',
                'min_length':'太短了',
                'max_length':'太长了',
            }
        )
        #正则验证:不能为空,16+
        password = fields.CharField(min_length=16,required=True)
        error_messages = {
            'required': '密码不能为空',
            'min_length': '太短了',
            'max_length': '太长了',
        }
        # email = fields.EmailField()   邮箱
        # email = fields.GenericIPAddressField()    IP
        # email = fields.IntegerField() #数字类型
    定义JSONResponse类
    def login(request):
        if request.method == "GET":
            return render(request,'login.html')
        else:
            obj = LoginForm(request.POST)
            ret = obj.is_valid()
            print(ret)#True or False
            if obj.is_valid():
                #用户输入的格式正确
                print(obj.cleaned_data)#字典类型#{'username': 'rootroot', 'password': 'rootrootrootrootroot'}
                return redirect('http://www.baidu.com')
            else:
                #用户输入格式错误
                print(obj.errors)#输出一个对象, <ul class="errorlist"><li>username<ul class="errorlist"><li>用户名太短了</li></ul></li><li>password<ul class="errorlist"><li>Ensure this value has at least 16 characters (it has 3).</li></ul></li></ul>
                # print(obj.errors['username'][0])
                # print(obj.errors['password'][0])
                return render(request,'login.html',{'obj':obj})
    定义login函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form method="POST" action="/login/">
        {% csrf_token %}
        <div>
            <p>
                用户名:<input type="text" name="username">{{ obj.errors.username.0 }}
            </p>
            <p>
                密 码:<input type="password" name="password">{{ obj.errors.password.0 }}
            </p>
    
            <input type="submit" value="提交"> {{ msg }}
        </div>
    </form>
    </body>
    </html>
    login.html
            #valid:有效的; 有法律效力的; 正当的; 健全的;
            user = request.POST.get('username')
            #不能为空,长度5-18位,必须邮箱格式
            if len(user) < 6:
                pass
    
            pwd = request.POST.get('password')
            #不能为空,长度5-18位,包含数字,字母,下划线
            if user == 'root' and pwd == '123':
                return redirect('http://www.baidu.com')
            else:
                return render(request,'login.html',{'msg':'用户名或密码错误'})
    杂项

    用户名密码的验证(比如用户名是邮箱格式)
    1.用户提交的格式验证,可以减轻数据库的压力
    2.当输入值的时候,输入非法的字符
    request.POST.get('username')
    request.POST.get('password')
    注册页面,登录页面(邮箱要用正则表达式验证)
    ip,port
    - 需要对请求数据做验证
    - 获取到数据然后进行验证
    邮箱正则(规则写一遍,不需要重复)
    - login:
    邮箱正则
    - register:
    邮箱正则

    问题:
    - 重复进行用户数据校验:正则,长度,是否为空
    - 无法记住上次提交内容,刷新页面数据消失

    Django提供 Form组件:
    1. 定义规则
    from django.forms import Form
    from django.forms import fields
    class xxx(Form):
    xx = fields.CharField(required=True,max_lenght.,min,error_messages=)
    fields:有一大堆的正则表达式,
    CharField:用户输入的数据必须是字符串
    required=True:不能为空
    error_messages:定义错误信息的中文显示
    required=True,max_lenght.,min,error_messages:四个参数
    2. 使用
    obj = xxx(request.POST)
    1).# 是否校验成功
    v = obj.is_valid()#怎么匹配
    # html标签name属性 = Form类字段名
    2).# 所有错误信息
    obj.errors

    3).# 正确信息
    obj.cleaned_data
    request.POST要传一个key,也就是前端传的name属性
    html中的username和password和views.py中的username一一匹配

    is_valid:在内部进行校验
    errors:所有的错误信息
    cleaned_data:成功之后的正确信息(字典类型)

  • 相关阅读:
    Linux下彻底卸载LibreOffice方法
    Docker查看关联容器的卷宗在本机的存储位置
    Ubuntu技巧之清理系统中无用的软件包
    进入一个docker容器
    Status Code:405 Method Not Allowed
    ubuntu安装docker
    今天犯的一个低级错误
    Eclipse中Ctrl+Shift+f快捷键无效的解决方式
    hdu 4742 Pinball Game 3D(三维LIS&amp;cdq分治&amp;BIT维护最值)
    linux下vi编辑文件
  • 原文地址:https://www.cnblogs.com/bingabcd/p/7113378.html
Copyright © 2020-2023  润新知