1.浏览器发过来请求,后台通过wsgi.py中封装的socket模块接收了请求,并且按照http协议进行解包-->封装成request对象
2.把request对象交给中间件,从上到下依次通过每个中间件
3.中间件处理完后交给url控制器进行路径分发,找到对应的视图函数views
4.视图函数进行orm数据操作和模板渲染等操作,之后return响应内容
5.响应内容倒序(从下到上)通过中间件,交给wsgi.py,通过http协议封装响应socket数据
6.最后把数据再交给浏览器
中间件:是介于request(请求)与response(响应)处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。
应用方向: 限流(限制访问频率),登录认证、权限认证、白名单控制等等
settings.py中的 MIDDLEWARE
# django提供的对所有请求和响应做一些统一处理的时候使用的
MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware‘,
‘django.contrib.sessions.middleware.SessionMiddleware‘,
‘django.middleware.common.CommonMiddleware‘,
]
1 在应用中创建一个py文件,名字随意 比如: mymiddleware.py
2 在py文件中写上如下内容(基于session登陆认证中间件)
from django.utils.deprecation import MiddlewareMixin
# Django提供的基础中间件类MiddlewareMixin,自定义中间件必须引入
from django.shortcuts import redirect
# 自定义类-->对所有请求进行一个统一的登录认证判断
class SessionLoginAuth(MiddlewareMixin): #自定义类继承MiddlewareMixin
# 登录认证白名单
white_list = [‘/login/‘, ]
def process_request(self, request):
#调用父类方法,对所有请求进行处理,自动触发进行
# 当前请求路径在白名单里面的就放行
current_path = request.path #获取当前请求路径
if current_path in self.white_list:
return None
is_login = request.session.get(‘is_login‘) #获取session值: True,None
if not is_login:
# 如果没有登录,那么直接跳转登录页面去登陆
return redirect(‘login‘)
# else:
# return None # return None就正常通过这个方法了,方法和函数return值不写,默认return None
3 将自己写的中间件类,配置到settings.py文件中的MIDDLEWARE配置列表中,才能生效
MIDDLEWARE = [ #添加路径
‘django.middleware.security.SecurityMiddleware‘,
‘app01.mymiddleware.SessionLoginAuth‘, # 配置自定义中间件
]
视图:views.py
def login(request):
if request.method == ‘GET‘:
return render(request, ‘login.html‘)
else:
print(request.POST)
uname = request.POST.get(‘username‘)
pwd = request.POST.get(‘password‘)
if uname == ‘root‘ and pwd == ‘123‘:
ret = redirect(‘home‘)
# 设置session
request.session[‘is_login‘] = True
request.session[‘uname‘] = uname
‘‘‘
1 生成随机字符串asdf,放到cookie中(sessionid:asdf)
2 在数据库表(django-session,先进行数据库同步指令)中,
data = 序列化然后加密is_login和uname数据
session_key session_data session_expire
asdf data 默认两周
‘‘‘
return ret
else:
return redirect(‘login‘)
def person(request):
return render(request, ‘person.html‘)
def home(request):
return render(request, ‘home.html‘)
# 退出登陆
def logout(request):
request.session.flush() # 退出登录:删除cookie,删除session数据
return redirect(‘login‘)
路由:urls.py
from app01 import views
urlpatterns = [
url(r‘^admin/‘, admin.site.urls),
url(r‘^login/‘, views.login, name=‘login‘),
url(r‘^home/‘, views.home,name=‘home‘),
url(r‘^person/‘, views.person,name=‘person‘),
url(r‘^logout/‘, views.logout,name=‘logout‘),
]
templates目录下HTML文件
login.html
<body>
<form action="" method="post">
{% csrf_token %}
用户名: <input type="text" name="username">
密码: <input type="password" name="password">
<input type="submit">
</form>
</body>
home.html
<body>
<h1>这是首页</h1>
<a href="{% url ‘person‘ %}">个人中心</a>
</body>
person.html
<body>
<h1>这是个人中心页面</h1>
<a href="{% url ‘logout‘ %}">注销</a>
</body>
# 记住4个方法,记住执行顺序
process_request(self,request) #最主要的方法
process_view(self, request, view_func, view_args, view_kwargs)
process_exception(self, request, exception)
process_response(self, request, response) #次要
# 知道即可,用不到
process_template_response(self,request,response)
作用: 对所有的请求方法进行同一处理
定义两个中间件类进行执行顺序的测试:
1.先执行中间件的process_request方法:
中间件1的process_request --> 中间件2的process_request
2.再执行视图函数:
home
1 在应用中创建一个py文件,名字随意 比如: mymiddleware.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print(‘MD1--process_request‘)
# return None
# 如果return None,那么程序会自动执行到下一个中间件的process_request方法
# 如果return的一个httpResponse对象,那么不会再执行后续中间件的process_request方法了,而是直接响应回去
return HttpResponse(‘xxxx‘)
class MD2(MiddlewareMixin):
def process_request(self,request):
print(‘MD2--process_request‘)
配置:settings.py中的middleware
MIDDLEWARE = [
# 将自己定义的中间件放到最后,为了方便使用内置中间件中对request对象封装的属性和方法
‘app01.mymiddleware.MD1‘, # 配置自定义中间件
‘app01.mymiddleware.MD2‘, # 配置自定义中间件
]
作用: 对所有的响应方法进行处理
定义两个中间件类进行执行顺序的测试:
1.先执行中间件的process_request方法:
中间件1的process_request --> 中间件2的process_request
2.再执行视图函数:
home
3.倒序执行process_response方法:
中间件2的process_response --> 中间件1的process_response
中间件mymiddleware.py代码
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print(‘MD1--process_request‘)
def process_response(self,requset, response):
"""
:param requset: 请求对象
:param response: 响应对象,视图函数的响应对象 -- HttpResponse对象
# render(request, ‘home.html‘)
:return:
"""
print(‘MD1--process_response‘)
# print(dir(response)) #response对象中的方法
# print(response.content) #html中内容
# 处理响应数据:加响应头键值对,控制响应状态码等等
ret = response
response[‘xx‘] = ‘oo‘
return ret # 必须return一个httpResponse对象,
class MD2(MiddlewareMixin):
def process_request(self,request):
print(‘MD2--process_request‘)
def process_response(self, requset, response):
print(‘MD2--process_response‘)
return response
作用: 对后续要执行的视图函数中的参数进行加工处理
定义两个中间件类进行执行顺序的测试:
1.先执行中间件的process_request方法:
中间件1的process_request --> 中间件2的process_request
2.然后执行process_view方法:
中间件1的process_view --> 中间件2的process_view
3.再执行视图函数:
home
4.倒序执行process_response方法:
中间件2的process_response --> 中间件1的process_response
中间件mymiddleware.py代码
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print(‘MD1--process_request‘)
def process_response(self,requset, response):
print(‘MD1--process_response‘)
return response # 必须return一个httpResponse对象,
def process_view(self, request, view_func, view_args, view_kwargs):
"""
:param request: 请求对象
:param view_func: 要被执行的视图函数对象
:param view_args: url无名分组正则匹配到的参数数据
:param view_kwargs: url有名分组正则匹配到的参数数据
:return:
"""
print(‘MD1--process_view‘)
print(view_func, view_args, view_kwargs)
class MD2(MiddlewareMixin):
def process_request(self,request):
print(‘MD2--process_request‘)
def process_response(self, request, response):
print(‘MD2--process_response‘)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(‘MD2--process_view‘)
作用: 对视图中的异常进行统一捕获和处理的(接口...)
定义两个中间件类进行执行顺序的测试:
1.先执行中间件的process_request方法:
中间件1的process_request --> 中间件2的process_request
2.然后执行process_view方法:
中间件1的process_view --> 中间件2的process_view
3.如果视图函数正常,执行视图函数,否则执行第4步:
home
4.倒序执行process_exception方法:
中间件2的process_exception --> 中间件1的process_exception
5.倒序执行process_response方法:
中间件2的process_response --> 中间件1的process_response
中间件mymiddleware.py代码
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
class MD1(MiddlewareMixin):
def process_request(self,request):
print(‘MD1--process_request‘)
def process_response(self,requset, response):
print(‘MD1--process_response‘)
return response # 必须return一个httpResponse对象,
def process_view(self, request, view_func, view_args, view_kwargs):
print(‘MD1--process_view‘)
# 对视图中的异常进行统一捕获和处理的
def process_exception(self, request, exception):
print(‘MD1--process_exception‘)
print(exception) # 视图返回的错误:xxxx -- 错误对象,
class MD2(MiddlewareMixin):
def process_request(self,request):
print(‘MD2--process_request‘)
def process_response(self, request, response):
print(‘MD2--process_response‘)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(‘MD2--process_view‘)
def process_exception(self, request, exception):
print(‘MD2--process_exception‘)
原文:https://www.cnblogs.com/jia-shu/p/14589847.html