湛江市seo网站设计报价,营销网站怎么做合适,机械建设网站,垦利住房和城乡建设局网站一、Django中间件
1.1 介绍
Django中的中间件是一个轻量级、底层的插件系统#xff0c;介于request与response处理之间的一道处理过程#xff08;用来处理特定业务的请求和响应#xff09;。中间件的设计为开发者提供了一种无侵入式的开发方式#xff0c;增强了Django框架…一、Django中间件
1.1 介绍
Django中的中间件是一个轻量级、底层的插件系统介于request与response处理之间的一道处理过程用来处理特定业务的请求和响应。中间件的设计为开发者提供了一种无侵入式的开发方式增强了Django框架的健壮性。
我们可以使用中间件在Django处理视图的不同阶段对输入或输出进行干预。
请求—中间件—响应 1.1.1 中间件配置
定义好中间件后需要在settings.py 文件中添加注册中间件
MIDDLEWARE [django.middleware.security.SecurityMiddleware, # 安全中间件django.contrib.sessions.middleware.SessionMiddleware, # 会话中间件corsheaders.middleware.CorsMiddleware, # 跨域请求中间件django.middleware.common.CommonMiddleware,django.middleware.csrf.CsrfViewMiddleware, # 防伪造跨域请求中间件django.contrib.auth.middleware.AuthenticationMiddleware, # 授权中间件django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware,
]【拓展】HTTP请求方法 GET 查询 POST 添加或修改数据 PUT 修改数据 DELETE 删除数据 OPTIONS: 探测服务器是否支持跨域 Access-Control-Allow[-Origin|Headers|Methods|Credentials] 访问-控制-允许-[源|头|方法|认证]
1.1.2 中间件的钩子函数生命周期
process_request: 请求到达时未到路由
process_view: 转到view处理函数之前
process_exception: 在view处理函数中抛出异常时
process_response: 在View响应之后向客户返回输出之前
process_template_response: 响应之前渲染模板之后1.1.3 自定义中间件类
from django.utils.deprecation import MiddlewareMixinclass AuthUserMiddleware(MiddlewareMixin):def process_request(self, request):passdef process_view(self, request, view, *args, **kwargs):passdef process_exception(self, request, exception):passdef process_response(self, request, response):return response1.1.4 通过中间件实现的功能
- 请求黑名单 1秒内允许2次请求正常非正常则在process_request()方法直接返回
- 提取授权用户的信息和权限验证 提前配置请求路径和用户权限
- 异常的友好提示
- 缓存数据减少数据库的交互次数 process_response() 对response对象进行序列化和缓存。
- 记录日志logging 模块1.2 线程方式实现缓存
import time
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
import threadingcached {}# 过期缓存监控的线程
class ExpireThread(threading.Thread):def clear(self, path, max_age):time.sleep(max_age)print(--checked--, path, cached.keys())if path in cached:cached.pop(path)def run(self):while True:time.sleep(1)print(--check--, cached.keys())for path, resp_max_age in cached.items():threading.Thread(targetself.clear,args(path, resp_max_age[-1])).start()class MyMiddleware(MiddlewareMixin):def process_request(self, request):print(--process_request---, request.path)# 判断当前请求路径是否在缓存中# 如果存在则直接返回响应if request.path in cached:return cached[request.path][0]def process_view(self, request, view, *args, **kwargs):# args 表示 view函数的位置参数# kwargs 表示 view函数的关键参数print(---process_view---, args)def process_exception(self, request, exception):print(request.path, dir(exception))print(----process_exception----, exception)return HttpResponse(h3Error Page 500: %s/h3 % str(exception))def process_response(self, request, response):print(---process_response---)if request.path not in cached:# 存入缓存内存print(---存入缓存---)cached[request.path] (response, 3)print(---缓存---, cached)return responseExpireThread().start()注册中间件 在settings.py文件中修改MIDDLEWARE如下所示
MIDDLEWARE [...apiapp.middleware.MyMiddleware,django.middleware.common.CommonMiddleware,...
]1.3 基于Redis实现缓存页面
from utils.caches import save_response, get_response, has_response
import pickle
import base64class RedisCacheMiddleware(MiddlewareMixin):def process_request(self, request):print(--process_request---, request.path)# 判断当前请求路径是否在缓存中# 如果存在则直接返回响应if has_response(request.path):resp_base_str get_response(request.path)resp_bytes base64.b32decode(resp_base_str.encode())response pickle.loads(resp_bytes)return responsedef process_response(self, request, response):print(---process_response---)# 存入缓存内存if not has_response(request.path):resp_bytes pickle.dumps(response) # 将python的任意对象序列化字段码# bQABWGZDKMFXGO3ZONB2HI4BOOJSXG4DPNZZWKCSIOR2HAUTFONYG63TTMUFHCABJQFYQC7LRAIUFQCAAAAAFresp_base64_str base64.b32encode(resp_bytes).decode()save_response(request.path, resp_base64_str, 3)return response二、日志模块
Python的日志模块是 logging
import logging2.1 日志的四大部分
日志是用于记录Logger程序中的一些重要信息的记录的信息按等级(Level)交给特定的处理器Handler按一定的格式Formatter进行处理打印、文件保存、上传网络和发送邮件等。
2.1.1 日志记录器 Logger
记录日志信息的唯一对象 根据不同的信息等级使用不同的记录方法 x.debug() 记录调试信息logging.DEBUG (10)x.info() 记录普通信息 logging.INFO (20)x.warning() 记录警告信息 loggin.WARNING (30)x.error() 记录错误信息 logging.ERROR (40)x.critical() 记录严重错误的信息 loggin.CRITICAL (50) 创建或获取记录器 logging.getLogger(name) 如果name为空则默认为root。记录器可以添加处理器和过滤器 x.addHandler(Handler())、 x.addFilter(Filter() )
2.1.2 日志处理器 Handler
作用 将记录器记录的相关日志信息进行特定业务的处理如写入文件的FileHandler、发送邮件的 SMTPHandler、上传远程服务器的HTTPHandler等。
【注意】处理器可以设置日志格式化 Formatter: h.setFormatter(Formatter())
StreamHandler 流处理器 控制台打印的FileHandler 文件处理器将日志消息写入到文件中HTTPHandler 网络处理器将日志消息上传到服务器SMTPHandler 邮件处理器将日志消息发送到指定邮件中。
日志记录器和处理器的关系
一个记录器可以添加多个处理器。
logger.addHandler(handler1)
logger.addHandler(handler2)logger logging.getLogger(network)
logger.setLevel(logging.INFO) handler1 StreamHandler()
handler1.setLevel(logging.INFO)handler2 FileHandler(network.log)
handler1.setLevel(logging.WARNING)logger.addHandler(handler1)
logger.addHandler(handler2)2.1.3 日志格式化 Formatter
作用 将记录日志信息进行格式化可以选择重要的信息、或者自定义格式的信息
经典的日志格式
[ %(asctime)s - %(levelname)s line %(lineno)s at %(pathname)s ] %(message)s如果给定的日志格式中变量不能完成业务需求时可以自定义
[ %(asctime)s - %(username)s: %(ip)s %(action)s ] %(message)s以上username、ip和action都属于自定义的格式变量在记录器记录信息时指定extra 参数 它是一个字典类型key即为扩展的变量名value即是它的值。
日志的格式 | %(name)s Name of the logger (logging channel) 记录器的名称| %(levelno)s Numeric logging level for the message (DEBUG, INFO,| WARNING, ERROR, CRITICAL) 数字形式的日志记录级别| %(levelname)s Text logging level for the message (DEBUG, INFO,| WARNING, ERROR, CRITICAL) 日志记录级别的文本名称| %(pathname)s Full pathname of the source file where the logging| call was issued (if available) 执行日志记录调用的源文件的路径名称| %(filename)s Filename portion of pathname 执行日志记录调用的源文件的文件名称| %(module)s Module (name portion of filename) 执行日志记录调用的模块名称| %(lineno)d Source line number where the logging call was issued| (if available) 执行日志记录调用的行号| %(funcName)s Function name 执行日志记录调用的函数名称| %(created)f Time when the LogRecord was created (time.time()| return value) 执行日志记录的时间| %(asctime)s Textual time when the LogRecord was created 日期和时间| %(msecs)d Millisecond portion of the creation time 毫秒部分| %(relativeCreated)d Time in milliseconds when the LogRecord was created,| relative to the time the logging module was loaded| (typically at application startup time)| %(thread)d Thread ID (if available) 线程ID| %(threadName)s Thread name (if available) 线程名称| %(process)d Process ID (if available) 进程ID| %(message)s The result of record.getMessage(), computed just as| the record is emitted 记录的消息
2.1.4 日志过滤器 Filter
作用 过滤一些敏感的记录日志信息。
2.2 日志的应用
2.2.1 标准使用
#!/usr/bin/python3
import logging
from logging import StreamHandler, FileHandler, Formatter, Filterclass MsgFilter(Filter):def filter(self, record): # record记录对象# print(dir(record)) # 查看记录器里面的方法return record.msg.find(混沌) -1logger logging.getLogger(middleware)
# 设置记录器的信息等级DEBUG - INFO - WARNING - ERROR - CRITICAL
logger.setLevel(logging.INFO) # 记录器可以记录INFO及以上等级信息# 添加日志过滤器
logger.addFilter(MsgFilter())# 创建日志处理器
handler1 StreamHandler() # 流处理器标准输出
handler1.setLevel(logging.INFO)
handler1.setFormatter(Formatter(fmt[ %(asctime)s - %(levelname)s] %(message)s,datefmt%Y-%m-%d %H:%M:%S
))# 向记录器添加处理器
logger.addHandler(handler1)handler2 FileHandler(error.log, encodingutf-8)
handler2.setLevel(logging.ERROR)
handler2.setFormatter(Formatter(fmt[ %(asctime)s - %(levelname)s line %(lineno)s at %(pathname)s ] %(message)s,datefmt%Y-%m-%d %H:%M:%S
))
logger.addHandler(handler2)if __name__ __main__:# x logging.getLogger(middleware) # 获取middleware的记录器logging.getLogger(middleware).debug(中午吃拉面)logging.getLogger(middleware).info(中午吃木桶饭)logging.getLogger(middleware).warning(中午吃凉皮)logging.getLogger(middleware).error(中午吃粥和夹馍)logging.getLogger(middleware).critical(下午吃混沌)
2.2.2 扩展格式化的使用
mylogger logging.getLogger(sys_action)
mylogger.setLevel(logging.INFO)myhandler StreamHandler()
myhandler.setLevel(logging.INFO)
myhandler.setFormatter(Formatter(fmt[ %(asctime)s - %(username)s: %(ip)s %(action)s ] %(message)s,datefmt%Y-%m-%d %H:%M:%S
))mylogger.addHandler(myhandler)if __name__ __main__:extra_info {username: admin,ip: 10.36.172.110,action: del category}logging.getLogger(sys_action).debug(中午吃拉面, extraextra_info)logging.getLogger(sys_action).info(中午吃木桶饭, extraextra_info)logging.getLogger(sys_action).warning(中午吃凉皮,extraextra_info)logging.getLogger(sys_action).error(中午吃粥和夹馍, extraextra_info)logging.getLogger(sys_action).critical(下午吃混沌, extraextra_info)