一、什么是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()
二、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 '''
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), ]
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)
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 '''
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() #数字类型
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})
<!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>
#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:成功之后的正确信息(字典类型)