Python全栈之路-Django(十三)
1 Django请求生命周期:
中间件 -> url -> 视图函数
Web框架的本质是socket
Django框架本身没有socket 使用的是第三方的socket
第三方的socket有很多,但是他们都需要遵循WSGI
规则,常用的第三方socket有,Django默认用wsgiref
生产中使用uwsgi
。
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()
2 MVC和MTV
models(数据库,模型) views(html模板) controllers(业务逻辑处理) --> MVC
models(数据库,模型) templates(html模板) views(业务逻辑处理) --> MTV
Django -> MTV
3 中间件
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。
应用:对所有请求或一部分请求做批量处理
中间件中可以定义五个方法,分别是:
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) *****
以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
md.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
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')
# 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')
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
def process_exception(self, request, exception):
print('m2.process_exception')
return HttpResponse('错误了...')
settings.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',
]
4 Form验证
普通的form表单存在的问题:
- 重复进行用户数据校验:正则、长度、是否为空等等...
- 无法记住上次提交内容,提交后页面刷新,数据消失
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_message=)
2 使用
obj = xxx(request.POST)
# 是否校验成功
v = obj.is_valid()
# html标签name属性 = Form类字段名
# 所有错误信息
obj.errors
# 正确信息
obj.cleaned_data
Form示例:
urls.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),
]
app01.views.py
from django.forms import Form
from django.forms import fields
class LoginForm(Form):
# 本质是正则验证
username = fields.CharField(
max_length=18,
min_length=6,
required=True,
error_messages={
'required': '用户名不能为空',
'max_length': '太长了',
'min_length': '太短了',
}
)
password = fields.CharField(min_length=16, required=True)
def login(request):
if request.method == 'GET':
return render(request,'login.html')
else:
obj = LoginForm(request.POST)
if obj.is_valid():
# 用户输入正确
print(obj.cleaned_data) # 字典类型
else:
# 用户输出错误
# print(obj.errors)
print(obj.errors['username'][0])
print(obj.errors['password'][0])
return render(request,'login.html',{'obj': obj})
templates.login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post">
{% csrf_token %}
<p><input type="text" name="username">{{ obj.errors.username.0 }}</p>
<p><input type="text" name="password">{{ obj.errors.password.0 }}</p>
<input type="submit" value="提交">
</form>
</body>
</html>