天天看點

第六章:Django 綜合篇 - 10:消息架構 message

在網頁應用中,我們經常需要在處理完表單或其它類型的使用者輸入後,顯示一個通知資訊給使用者。

對于這個需求,Django提供了基于Cookie或者會話的消息架構messages,無論是匿名使用者還是認證的使用者。這個消息架構允許你臨時将消息存儲在請求中,并在接下來的請求(通常就是下一個請求)中提取它們并顯示。每個消息都帶有一個特定的level标簽,表示其優先級(例如info、 warning或error)。

一、啟用消息架構

Django的messages消息架構的實作,依賴messages中間件和對應的context processor。

通過

django-admin startproject xxx

指令建立工程時,已經預設在settings.py中開啟了消息架構功能需要的所有的設定:

  • INSTALLED_APPS中注冊的'django.contrib.messages'。
  • MIDDLEWARE中添加'django.contrib.sessions.middleware.SessionMiddleware'和'django.contrib.messages.middleware.MessageMiddleware'。Django的messages架構預設使用的存儲後端為sessions。是以Session中間件必須被啟用,并出現在Message中間件之前。
  • TEMPLATES設定中的DjangoTemplates選項包含的'context_processors'配置項要包含'django.contrib.messages.context_processors.messages'。

二、配置消息引擎

通常我們使用預設的就好,可以跳過這節,但如果真有需要,也可以配置:

1. 存儲後端

Django提供了三種内置的消息存儲後端:

class storage.session.SessionStorage class storage.cookie.CookieStorage class storage.fallback.FallbackStorage

FallbackStorage是預設的存儲後端。如果它不适合你的需要,你可以通過設定MESSAGE_STORAGE選擇另外一個存儲後端,例如:

MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
           

2. 消息級别

消息架構的級别是可配置的,與Python的logging子產品類似

Django内置的message級别有下面幾種:

級别 說明
DEBUG 将在生産部署中忽略(或删除)的與開發相關的消息
INFO 普通提示資訊
SUCCESS 成功資訊
WARNING 警告資訊
ERROR 已經發生的錯誤資訊

MESSAGE_LEVEL

設定可以用來改變記錄的最小級别(參考前面的Django設定章節),小于這個級别的消息将被忽略。

3. 消息樣式

通常,我們在前端HTML頁面中,希望給不同級别的消息,增加不同的CSS樣式,比如警告為黃色,error為紅色等等。

Django為我們提供了一個預設的樣式對應關系:

樣式
debug
info
success
warning
error

也就是說SUCCESS級别的消息,在前端會被賦予一個success樣式class。

若要修改消息級别的預設樣式,設定

MESSAGE_TAGS

,按如下例子所示:。

from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
    messages.INFO: '',
    50: 'critical',
}
           

三、使用消息架構

1. 添加消息

方法原型:add_message(request, level, message, extra_tags='', fail_silently=False)[source]

新增一條消息:

from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')
           

提供請求對象request(直接用就行),消息級别、消息内容字元串三個參數即可。

或者使用下面的快捷方式

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.')
           

2. 顯示消息

方法原型:get_messages(request)[source]

在你的模闆檔案中,像下面這樣使用:

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}
           

相關說明:

  • 通過if判斷是否有消息;
  • messages是一個清單,必須用for标簽循環它;
  • 即使你知道隻有一條消息,也要疊代messages清單,否則下個請求中,上個請求的消息不會被清除。
  • 可以通過message.tags拿到每個消息的CSS樣式

有一個

DEFAULT_MESSAGE_LEVELS

變量,它映射消息級别的名稱到它們的數值:

{% 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 %}
           

說明:

  • 可以通過message.level拿到目前消息的級别數值;
  • 将它與DEFAULT_MESSAGE_LEVELS.ERROR進行對比;
  • 如果一樣,就說明目前消息級别為ERROR,需要顯示到頁面上。

在模闆的外面,比如視圖中,可以使用

get_messages()

方法擷取消息:

from django.contrib.messages import get_messages

storage = get_messages(request)
for message in storage:
    do_something_with_the_message(message)
           
  • get_messages()傳回的是存儲後端的一個執行個體。
  • 循環這個執行個體,可以獲得每條消息

對于每一個消息執行個體,都包含下面的屬性,可以在模版或視圖中調用:

  • message: 消息的實際内容文本。不要使用message.message,直接message。
  • level: 消息級别,一個整數。
  • tags: 一個字元串,由該消息的所有标簽(extra_tags和tags)組合而成,組合時用空格分割開這些标簽。
  • extra_tags

    : 一個字元串,由該消息的定制标簽組合而成,并用空格分割。預設為空。
  • level_tag

    : 目前消息級别對應的CSS字元串,前面介紹過。

3. 自定義消息級别

消息級别隻是一個整數常量,是以,可以定義自己的級别常量,例如:

CRITICAL = 50

def my_view(request):
    messages.add_message(request, CRITICAL, 'A serious error occurred.')
           

在自定義消息級别時,應小心避免覆寫現有級别。内置級别的值為:

對應整數值
10
20
25
30
40

如果你需要在HTML或CSS中使用自定義級别,則需要通過

MESSAGE_TAGS

設定提供相應的映射關系。

4. 自定義每個請求的最小記錄級别

每個請求都可以通過

set_level()

方法設定最小記錄級别,如下所示:

from django.contrib import messages

# 修改最小級别為DEBUG
messages.set_level(request, messages.DEBUG)
messages.debug(request, 'Test message...')

# 在另外一個視圖中修改最小級别為WARNING
messages.set_level(request, messages.WARNING)
messages.success(request, 'Your profile was updated.') # 被忽略,不記錄
messages.warning(request, 'Your account is about to expire.') # 記錄

# 将最小級别恢複到預設值
messages.set_level(request, None)
           

set_level()

方法接收request為第一參數,消息級别為第二參數。

類似的,目前有效的記錄級别可以用

get_level()

方法擷取:

from django.contrib import messages
current_level = messages.get_level(request)
           

5. 添加額外的消息CSS樣式

要添加自定義的消息CSS樣式,可以通過extra_tags參數:

messages.add_message(request, messages.INFO, 'Over 9000!', extra_tags='dragonball')
messages.error(request, 'Email box full', extra_tags='email')
           

四、消息過期機制

預設情況下,如果包含消息的疊代器完成疊代後,目前請求中的消息都将被删除。

如果你不想這麼做,想保留這些消息,那麼需要顯式的指定used參數為False,如下所示:

storage = messages.get_messages(request)
for message in storage:
    do_something_with(message)
storage.used = False