使用message组件要在seetings中配置
①INSTALLED_APPS (项目需要什么功能都放在这 既可以有数据库,又可以写代码,html文件,和自己写的APP一个道理)
②MIDDLEWARE 中间件 (请求进来做什么,请求走的时候做什么)
③TEMPLATES (模板,在html页面中操作方便)
④第四个位置可以放在任意地方 有三种配置(将数据保存在cookie中或session中,或者全部保存)
使用方法
设置值
第一个参数request .第二个参数 消息的级别,messages.SUCCESS不一定要这么写.第三个参数,自己写具体的参数. 以列表的形式存在
1 from django.contrib import messages 2 messages.add_message(reqeust, messages.SUCCESS, "删除成功") 3 messages.add_message(reqeust, messages.ERROR, "删除失败")
在视图中读取值(使用python代码) 循环读取到messages, 读取到的同时并删除 (类里面写的__iter__方法所以可以循环)
1 from django.contrib.messages.api import get_messages 2 messages = get_messages(request) 3 for msg in messages: 4 print(msg)
使用html代码读取值
<ul> {% for message in messages %} <li>{{ message.tags }} {{ message }}</li> {% endfor %} </ul>
源码分析
message是一个对象(包裹),可以包裹很多数据

1 class Message: 2 """ 3 Represent an actual message that can be stored in any of the supported 4 storage classes (typically session- or cookie-based) and rendered in a view 5 or template. 6 """ 7 8 def __init__(self, level, message, extra_tags=None): 9 self.level = int(level) 10 self.message = message 11 self.extra_tags = extra_tags 12 13 def _prepare(self): 14 """ 15 Prepare the message for serialization by forcing the ``message`` 16 and ``extra_tags`` to str in case they are lazy translations. 17 """ 18 self.message = str(self.message) 19 self.extra_tags = str(self.extra_tags) if self.extra_tags is not None else None 20 21 def __eq__(self, other): 22 if not isinstance(other, Message): 23 return NotImplemented 24 return self.level == other.level and self.message == other.message 25 26 def __str__(self): 27 return str(self.message) 28 29 @property 30 def tags(self): 31 return ' '.join(tag for tag in [self.extra_tags, self.level_tag] if tag) 32 33 @property 34 def level_tag(self): 35 return LEVEL_TAGS.get(self.level, '')
View Code
request,level,message分别对应设置值时候的参数,extra_tags=”:可以自己写点东西,一般不用写.fail_silently=False,是在if not fail_silently 做的一个异常处理,也就是说如果有异常了安安静静的在那不要报错.
重点: messages = request._messages 在request中读取到了一个对象,return messages.add(level, message, extra_tags) 调用了messages.add,把这个三个参数传过去了.
request_messages是在’django.contrib.messages.middleware.MessageMiddleware’ 这个中间件中定义的,看是在第四个位置中哪个存储的对象,SessionStorage对象(第四个位置设置的哪个就是那个对象)
所以messages = request._messages就是声明了一个SessionStorage的对象(第四个位置设置的哪个就是那个对象),SessionStorage源码中实例化了这个对象,下面有调用了messages.add(level, message, extra_tags)方法,SessionStorage这个类中没有message.add方法,在父类BaseStorage中,接收了三个参数def add(self, level, message, extra_tags=”).最后封装给了message = Message(level, message, extra_tags=extra_tags), 总而言之绕了一圈,最终传入进来的值都会封装给Message对象
def add_message(request, level, message, extra_tags='', fail_silently=False): """ Attempt to add a message to the request using the 'messages' app. """ try:
#SessionStorage的对象(第四个位置设置的哪个就是那个对象)
messages = request._messages
""" except AttributeError: if not hasattr(request, 'META'): raise TypeError( "add_message() argument must be an HttpRequest object, not " "'%s'." % request.__class__.__name__ ) if not fail_silently: raise MessageFailure( 'You cannot add messages without installing ' 'django.contrib.messages.middleware.MessageMiddleware' )
""" else: return messages.add(level, message, extra_tags)
SessionStorage源码中实例化了这个对象
SessionStorage父类中
Message中
1 class Message: 2 """ 3 Represent an actual message that can be stored in any of the supported 4 storage classes (typically session- or cookie-based) and rendered in a view 5 or template. 6 """ 7 8 def __init__(self, level, message, extra_tags=None): 9 self.level = int(level) 10 self.message = message 11 self.extra_tags = extra_tags 12 13 def _prepare(self): 14 """ 15 Prepare the message for serialization by forcing the ``message`` 16 and ``extra_tags`` to str in case they are lazy translations. 17 """ 18 self.message = str(self.message) 19 self.extra_tags = str(self.extra_tags) if self.extra_tags is not None else None 20 21 def __eq__(self, other): 22 if not isinstance(other, Message): 23 return NotImplemented 24 return self.level == other.level and self.message == other.message 25 26 def __str__(self): 27 return str(self.message) 28 29 @property 30 def tags(self):
# 自己的tag和通过extra传进来的tag都传进来通过空格拼接 31 return ' '.join(tag for tag in [self.extra_tags, self.level_tag] if tag) 32 33 @property 34 def level_tag(self): 35 return LEVEL_TAGS.get(self.level, '')
level_tag拿到的就是下面这个字典,在seetings中还可以自定义
DEFAULT_TAGS