您现在的位置是: 网站首页 >Django Django

Django使用message框架向模板中推送消息内容

admin2018年11月1日 18:39 Django | Html | Python 1097人已围观

# Django模板中使用消息message框架 在web应用程序中,通常需要在处理表单或其他类型的用户输入之后向用户显示一次性通知消息(也称为“flash message”)。 为此,Django为匿名用户和经过身份验证的用户提供了对基于cookie和会话的消息传递的完全支持。messages框架允许您在一个请求中临时存储消息,并检索它们以在后续请求(通常是下一个请求)中显示。每条消息都有一个确定优先级的特定级别(例如,info、warning或error)。 ## 启用消息 消息是通过中间件类和相应的上下文处理器实现的。 由`django-admin startproject`创建的默认`settings.py`已经包含了启用消息功能所需的所有设置: - `django.contrib.messages`在`INSTALLED_APPS`中。 - 中间件包含`django.contrib.sessions.middleware.SessionMiddleware`和`django.contrib.messages.middleware.MessageMiddleware`,默认存储后端依赖于会话。这就是为什么必须启用SessionMiddleware,并且在中间件中的MessageMiddleware之前。 - 在模板设置中定义的DjangoTemplates的`context_processor`选项包含`django.contrib.messages.context_processors.messages`。 如果你不想使用消息,你可以删除来自您的`INSTALLED_APPS`的`django.contrib.messages`,来自MIDDLEWARE的MessageMiddleware,来自TEMPLATES的messages上下文处理器。 ## 配置消息引擎 ### 存储后端 消息框架可以使用不同的后端存储临时消息。 Django在`django.contrib.messages`中提供了三个内置的存储类: - `class storage.session.SessionStorage` 该类存储请求会话中的所有消息。因此它需要Django的`contrib.sessions`的应用程序。 - `class storage.cookie.CookieStorage` 该类将消息数据存储在cookie中(使用秘密散列签名以防止操作),以便在请求之间持久化通知。如果cookie数据大小超过2048字节,则删除旧消息。 - `class storage.fallback.FallbackStorage` 这个类首先使用`CookieStorage`,然后返回到使用`SessionStorage`来存储不能放入单个cookie的消息。它还需要Django的`contrib.sessions`的应用程序。 这种行为尽量避免向会话写入内容。它应该在一般情况下提供最好的性能。 `FallbackStorage`是默认的存储类。如果它不适合您的需要,您可以通过设置`MESSAGE_STORAGE`的完整导入路径来选择另一个存储类,例如: ```python MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' ``` - `class storage.base.BaseStorage` 要编写自己的存储类,子类化`django.contrib.messages.storage.base`的`BaseStorage`,创建和实现`_get`和`_store`方法。 ### 消息等级 消息框架基于类似于Python日志模块的可配置级别体系结构。消息级别允许您按类型对消息进行分组,以便在视图和模板中以不同的方式过滤或显示消息。 内置级别,可以从`django.contrib.messages`直接导入包括: | 变量 | 用途 | | --- | --- | | `DEBUG` | 将在生产部署中被忽略(或删除)的与开发相关的消息 | | `INFO` | 为用户提供信息消息 | | `SUCCESS` | 行为成功消息 | | `WARNING` | 失败并没有发生,但可能即将发生 | | `ERROR` | 一个操作没有成功,或者发生了其他一些失败 | `MESSAGE_LEVEL`设置可用于更改最低记录级别(或可根据请求更改)。试图添加低于此级别的消息将被忽略。 ### 消息标签 消息标签是消息级别的字符串表示形式,加上直接在视图中添加的任何额外标记(有关更多细节,请参阅下面添加额外消息标记)。标记存储在字符串中,并由空格分隔。通常,消息标记被用作**CSS类**,以根据消息类型定制消息样式。默认情况下,每个级别都有一个标签,它是自己常量的小写版本: | 级别变量 | 标签 | | --- | --- | | `DEBUG` | `debug` | | `INFO` | `info` | | `SUCCESS` | `success` | | `WARNING` | `warning` | | `ERROR` | `error` | 要更改消息级别的默认标记(内置或自定义),请将`MESSAGE_TAGS`setting设置为包含希望更改的级别的字典。由于这扩展了默认标签,只需要为您希望覆盖的级别提供标记: ```python from django.contrib.messages import constants as messages MESSAGE_TAGS = { messages.INFO: '', 50: 'critical', } ``` ## 在视图和模板中使用消息 **`add_message(request, level, message, extra_tags='', fail_silently=False)`** ### 添加消息 要添加消息,直接使用message的`add_messages`方法 ```python from django.contrib import messages messages.add_message(request, messages.INFO, 'Hello world.') ``` 一些快捷方式提供了一种标准的方式来添加带有常用标记的消息(通常表示为消息的HTML类): ```python messages.debug(request, '%s SQL statements were executed.' % count) messages.info(request, 'Three credits remain in your account.') messages.success(request, 'Profile details updated.') messages.warning(request, 'Your account expires in three days.') messages.error(request, 'Document deleted.') ``` ### 添加消息 **`get_messages(request)`** 在您的模板中,使用如下内容: ```html {% if messages %} <ul class="messages"> {% for message in messages %} <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> {% endfor %} </ul> {% endif %} ``` 如果您正在使用上下文处理器,您的模板应该使用RequestContext呈现。否则,确保消息对模板上下文可用。 即使您知道只有一条消息,您仍然应该遍历消息序列,否则消息存储将不会为下一个请求清除。 上下文处理器还提供了`DEFAULT_MESSAGE_LEVELS`变量,该变量是消息级别名称与其数值的映射: ```python {% if messages %} <ul class="messages"> {% for message in messages %} <li{% if message.tags %} class="{{ message.tags }}"{% endif %}> {% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}Important: {% endif %} {{ message }} </li> {% endfor %} </ul> {% endif %} ``` 在模板之外,可以使用`get_messages()`: ```python from django.contrib.messages import get_messages storage = get_messages(request) for message in storage: do_something_with_the_message(message) ``` 例如,可以获取所有消息,以JSONResponseMixin而不是TemplateResponseMixin返回它们。 `get_messages()`将返回配置的存储后端实例。 更多内容参看:https://docs.djangoproject.com/zh-hans/2.1/ref/contrib/messages/ ## 消息类 **`class storage.base.Message`** 当您在模板中循环消息列表时,得到的是消息类的实例。这是一个非常简单的对象,只有几个属性: - `消息`:消息的实际文本。 - `level`:描述消息类型的整数(参见上面的message levels部分)。 - `标记`:由空格分隔的所有消息标记(extra_tags和level_tag)组合而成的字符串。 - `extra_tags`:一个字符串,包含此消息的自定义标记,用空格分隔。默认为空。 - `level_tag`:级别的字符串表示形式。默认情况下,它是相关常量名称的小写版本,但如果需要,可以通过使用`MESSAGE_TAGS`设置来更改。 ### 创建自定义消息级别 消息级别不仅仅是整数,所以可以定义自己的级别常量,并使用它们创建更多定制的用户反馈,例如: ```python CRITICAL = 50 def my_view(request): messages.add_message(request, CRITICAL, 'A serious error occurred.') ``` 在创建自定义消息级别时,应该小心避免重载现有级别。内置级别的值为: | 级别常量 | 值 | | --- | --- | | `DEBUG` | 10 | | `INFO` | 20 | | `SUCCESS` | 25 | | `WARNING` | 30 | | `ERROR` | 40 | 如果需要在HTML或CSS中标识自定义级别,则需要通过`MESSAGE_TAGS`设置提供映射。 > 如果要创建可重用的应用程序,建议只使用内置的消息级别,而不依赖任何自定义级别。 ### 更改每个请求的最低记录级别 可以通过`set_level`方法为每个请求设置最低记录级别: ```python from django.contrib import messages # Change the messages level to ensure the debug message is added. messages.set_level(request, messages.DEBUG) messages.debug(request, 'Test message...') # In another request, record only messages with a level of WARNING and higher messages.set_level(request, messages.WARNING) messages.success(request, 'Your profile was updated.') # ignored messages.warning(request, 'Your account is about to expire.') # recorded # Set the messages level back to default. messages.set_level(request, None) ``` 同样,可以使用`get_level`检索当前有效级别: ```python from django.contrib import messages current_level = messages.get_level(request) ``` 有关最低记录级别函数的更多信息,请参见上面的消息级别。 ### 添加额外的消息标签 为了对消息标记进行更直接的控制,您可以选择为任何add方法提供包含额外标记的字符串: ```python messages.add_message(request, messages.INFO, 'Over 9000!', extra_tags='dragonball') messages.error(request, 'Email box full', extra_tags='email') ``` 在该级别的默认标记之前添加额外的标记,并将它们分隔开来。 ### 在禁用消息框架时静默失败 如果您正在编写一个可重用的应用程序(或其他代码片段),并且希望包含消息传递功能,但是如果用户不希望启用它,您可能会向`add_message`方法家族传递一个额外的关键字参数`fail_silent =True`。例如: ```python messages.add_message( request, messages.SUCCESS, 'Profile details updated.', fail_silently=True, ) messages.info(request, 'Hello world.', fail_silently=True) ``` > 设置`fail_silent =True`只会隐藏当消息框架被禁用并试图使用`add_message`方法家族之一时发生的MessageFailure。它不会隐藏由于其他原因可能发生的失败。 ## 在基于类的视图中添加消息 **`class views.SuccessMessageMixin`** ### success\_message属性 向基于`FormView`的类添加一个`success`消息属性 `get_success_message(cleaned_data)`:`cleaned_data`是从用于字符串格式化的表单中清除的数据,例如 ```python from django.contrib.messages.views import SuccessMessageMixin from django.views.generic.edit import CreateView from myapp.models import Author class AuthorCreate(SuccessMessageMixin, CreateView): model = Author success_url = '/success/' success_message = "%(name)s was created successfully" ``` 通过使用`%(field_name)`的语法,可以使用从表单中清理出来的数据进行字符串插值。 ### get\_success\_message(self, cleaned_data)方法 对于ModelForms,如果需要从保存的对象访问字段,请覆盖`get_success_message()`方法。例如: ```python from django.contrib.messages.views import SuccessMessageMixin from django.views.generic.edit import CreateView from myapp.models import ComplicatedModel class ComplicatedCreate(SuccessMessageMixin, CreateView): model = ComplicatedModel success_url = '/success/' success_message = "%(calculated_field)s was created successfully" def get_success_message(self, cleaned_data): return self.success_message % dict( cleaned_data, calculated_field=self.object.calculated_field, ) ``` ## 过期的信息 将标记为在迭代存储实例时清除消息(在处理响应时清除消息)。 为了避免消息被清除,可以在迭代后将消息存储设置为`False` ```python storage = messages.get_messages(request) for message in storage: do_something_with(message) storage.used = False ``` # 使用实例 ## 创建消息分类显示模板 当消息的类型不同时,显示不同的样式,创建message-alert-content.html文件 ```html {% if messages %} {% for message in messages %} {% if message.level == DEFAULT_MESSAGE_LEVELS.INFO %} <div class="alert alert-info alert-dismissable"> <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button> 【信息】:{{ message }} </div> {% endif %} {% if message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %} <div class="alert alert-success alert-dismissable"> <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button> 【成功】:{{ message }} </div> {% endif %} {% if message.level == DEFAULT_MESSAGE_LEVELS.WARNING %} <div class="alert alert-warning alert-dismissable"> <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button> 【警告】:{{ message }} </div> {% endif %} {% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %} <div class="alert alert-danger alert-dismissable"> <button aria-hidden="true" data-dismiss="alert" class="close" type="button">×</button> 【错误】:{{ message }} </div> {% endif %} {% endfor %} {% endif %} ``` ## UpdateView中使用message ### form_valid定义消息添加 基于类的视图可以定义在验证表单的函数中 ```python @method_decorator(login_required, name='dispatch') class BlogNoticeUpdate(UpdateView): model = BlogNotice template_name = 'rearend/blog-notice-edit.html' form_class = BlogNoticeForm context_object_name = 'blog_notice' # success_url = reverse_lazy('blog_admin:blog_notice') # 这儿不能使用reverse def get_success_url(self): # 自定义跳转链接 return reverse_lazy('blog_admin:blog_notice', kwargs=self.kwargs) def form_valid(self, form): messages.success(self.request, '更新成功,该页面显示更新后的内容!') return super(BlogNoticeUpdate, self).form_valid(form) ``` **当然可以直接添加类方法,需要继承xxxMessageMixin父类** ### 模板中包含消息模块 ```html <div class="ibox-content"> <!--消息弹出--> {% include 'rearend/includes/message-alert-content.html' %} <form class="form-horizontal" method="post" action="."> <div class="form-group"> <label for="id_blogger" class="col-sm-2 control-label">博主:</label> <div class="col-sm-10"> <input type="text" name="blogger" value="{{ form.blogger.value }}" maxlength="10" required="" id="id_blogger" class="form-control"> </div> </div> <div class="form-group"> <label for="id_title" class="col-sm-2 control-label">公告标题:</label> <div class="col-sm-10"> <input type="text" name="title" value="{{ form.title.value }}" maxlength="20" required="" id="id_title" class="form-control"> </div> </div> <div class="form-group"> <label for="id_content" class="col-sm-2 control-label">公告:</label> <div class="col-sm-10"> <textarea name="content" cols="40" rows="10" id="id_content" class="form-control">{{ form.content.value }}</textarea> </div> </div> {% csrf_token %} <div class="hr-line-dashed"></div> <div class="form-group"> <div class="col-sm-4 col-sm-offset-2"> <button class="btn btn-primary" type="submit">保存内容</button> </div> </div> </form> </div> ``` ![BLOG_20181101_183938_95](/media/blog/images/2018/11/BLOG_20181101_183938_95.png "博客图集BLOG_20181101_183938_95.png") ## 函数中使用message 直接在相应的位置添加 ```python messages.success(request, '删除专题成功!') messages.error(request, 'xxx') # 使用消息框架 ```

很赞哦! (0)

文章交流

  • emoji
0人参与,0条评论

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行2077天
  • 系统信息:Linux
  • 后台程序:Python: 3.8.10
  • 网站框架:Django: 3.2.6
  • 文章统计:256 篇
  • 文章评论:60 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 公众号:微信扫描二维码,关注我们
  • QQ群:QQ加群,下载网站的学习源码
返回
顶部
标题 换行 登录
网站