首页 > 其他 > 详细

Django中间件部分

时间:2017-07-03 23:07:20      阅读:475      评论:0      收藏:0      [点我收藏+]

一、什么是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": "\u9519\u8bef\u4fe1\u606f"}
    # 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:成功之后的正确信息(字典类型)

 

Django中间件部分

原文:http://www.cnblogs.com/bingabcd/p/7113378.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!