如何保留Django messages历史记录 查看会话启动以来全部报错信息
Django messages框架历史报错记录留存的可行方案
Django默认messages框架采用读取即销毁的存储逻辑,消息渲染展示后就会自动清除,要实现会话内甚至跨会话的历史记录留存,可按需选择以下三种方案:
方案1:自定义messages存储后端(轻量无侵入)
适合仅需要会话内留存、不想改动原有业务代码的场景,核心是重写存储逻辑,取消读取后自动清除的规则:
- 继承默认的SessionStorage类,修改读取逻辑,不标记消息为已使用
from django.contrib.messages.storage.session import SessionStorage class PersistentMessageStorage(SessionStorage): def _get(self, *args, **kwargs): # 直接返回会话中存储的所有消息,不触发自动清除逻辑 messages = self.request.session.get(self.session_key, []) return messages, False
- 在
settings.py中替换默认存储后端
MESSAGE_STORAGE = '你的应用路径.PersistentMessageStorage'
- 后续需要清空历史时,主动调用
storage.clear()即可,也可以给消息加is_read标记区分已读未读状态。
方案2:数据库存储历史消息(支持永久跨会话留存)
适合需要用户登录后跨设备、跨会话查看历史报错的场景:
- 新增历史消息存储模型
from django.db import models from django.contrib.auth import get_user_model from django.contrib.messages import constants as msg_levels class MessageHistory(models.Model): user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, null=True) level = models.IntegerField(choices=[ (msg_levels.DEBUG, '调试'), (msg_levels.INFO, '信息'), (msg_levels.SUCCESS, '成功'), (msg_levels.WARNING, '警告'), (msg_levels.ERROR, '错误') ]) content = models.TextField() create_time = models.DateTimeField(auto_now_add=True) is_read = models.BooleanField(default=False)
- 监听
message_sent信号自动存库,不需要改动原有messages.error调用逻辑
from django.contrib.messages.signals import message_sent from django.dispatch import receiver @receiver(message_sent) def save_msg_to_history(sender, message, level, request, **kwargs): if request.user.is_authenticated: # 登录用户直接存库 MessageHistory.objects.create( user=request.user, level=level, content=message.message ) else: # 匿名用户临时存到session if 'msg_history' not in request.session: request.session['msg_history'] = [] request.session['msg_history'].append({ 'level': level, 'content': message.message }) request.session.modified = True
- 你原有的报错代码
messages.error(request, ('ERROR: Your milestone was not created. Milestone points must be numeric. Please try again.'))不需要做任何修改,信号会自动把消息存入历史。
方案3:Session单独存历史(最小改动)
不想修改默认messages逻辑也不想加模型的话,可以封装一个消息发送工具方法,每次发消息时额外往session存一份:
from django.contrib import messages from django.utils import timezone def add_msg_with_history(request, level, content): # 调用原生messages方法保证即时提示正常工作 messages.add_message(request, level, content) # 额外存入session的历史列表 if 'msg_history' not in request.session: request.session['msg_history'] = [] request.session['msg_history'].append({ 'level': level, 'content': content, 'time': timezone.now().isoformat() }) request.session.modified = True # 调用时代码替换为封装方法即可 # add_msg_with_history(request, messages.ERROR, 'ERROR: Your milestone was not created. Milestone points must be numeric. Please try again.')
查看历史时直接读取request.session.get('msg_history', [])即可,会话过期后历史自动清除,适合临时留存的需求。
内容的提问来源于stack exchange,提问作者kikee1222
相关产品推荐
相关产品推荐

