1. 程式人生 > >Django中全局Context處理器

Django中全局Context處理器

ast from .site tco ons desc ces 項目 創建

1.模板標簽和模板變量

模板標簽在{% %}中定義:

{% if is_logged_in %}
    Thanks for logging in!
{% else %}
    Please log in.
{% endif %}

模板變量在 { }中定義:

My first name is {{ first_name }}. My last name is {{ last_name }}.

2.Context處理器和 RequestContext處理器

context 是一個傳遞給模板的名稱到值的映射(類似Python字典)。通過從context獲取值來替換模板中變量並執行所有的模板標簽來實現模板渲染。

from django.template import loader, Context

def view_1(request):
    # ...
    t = loader.get_template(template1.html)
    c = Context({
        app: My app,
        user: request.user,
        ip_address: request.META[REMOTE_ADDR],
        message: I am view 1.
    })
    return t.render(c)

def view_2(request): # ... t = loader.get_template(template2.html) c = Context({ app: My app, user: request.user, ip_address: request.META[REMOTE_ADDR], message: I am the second view. }) return t.render(c)

在上述代碼中定義了兩個視圖,他們除了message不同其余信息都相同,而這樣分別定義顯然是冗余的。所以需要引入 RequestContext處理器。

from django.shortcuts import render_to_response
from django.template import RequestContext

def custom_proc(request):   # context處理器,它接收一個 HttpRequest 對象,然後返回一個字典
    "A context processor that provides ‘app‘, ‘user‘ and ‘ip_address‘."
    return {
        app: My app,
        user: request.user,
        ip_address: request.META[REMOTE_ADDR]
    }

def view_1(request):
    # ...
    return render_to_response(template1.html,
        {message: I am view 1.},
        context_instance=RequestContext(request, processors=[custom_proc])) # 接受processors參數

def view_2(request):
    # ...
    return render_to_response(template2.html,
        {message: I am the second view.},
        context_instance=RequestContext(request, processors=[custom_proc]))

上述代碼中利用 render_to_response 代替了render使得可以不用手動載入模板。值得註意的是,在上面這種方法中雖然看似減少了冗余代碼,但是由於需要不斷鍵入processors參數,所以依然不夠簡潔。

所以djang提供對全局 context 處理器的支持。在settings.py 中,有類似代碼:

TEMPLATES = [
    {
        BACKEND: django.template.backends.django.DjangoTemplates,
        DIRS: [
            os.path.join(BASE_DIR, templates)
        ],
        APP_DIRS: True,
        OPTIONS: {
            context_processors: [   # 以下定義了默認的全局文本處理器
                django.template.context_processors.debug,
                django.template.context_processors.request,
                django.contrib.auth.context_processors.auth,
                django.contrib.messages.context_processors.messages,
                blog.views.custom_proc,  # 見下文代碼
            ],
        },
    },
]

以下方法實現全局化文本處理器。

  • 建議在項目的應用(app)或項目(project)下創建一個叫做context_processors.py的文件。只要它們存放在你的Python的搜索路徑中,它們放在哪個物理路徑並不重要,這樣你可以在CONTEXT_PROCESSORS設置裏指向它們。
  • 在context_processors.py中創建你需要定義的處理器,使每個context處理器完成盡可能小的功能。
  • 將該文本處理器引入到 context_processors 目錄下,如上文代碼。

特別的,不去額外定義 context_processors.py ,而在 views.py 中直接寫好 custom_proc 後,則可以將其目錄加入到 context_processors 中。eg:上述代碼中的 def custom_proc(request):

3. 調用 settings.py 中的配置信息作為全局調用

  • 在 settings.py 中加入你要替換的信息:
SITE_NAME = ‘。。。的個人博客
SITE_DESC = Python開發 && Django開發
  • 在 views.py 中引入參數:
from django.conf import settings
def global_setting(request):
    return {SITE_NAME: settings.SITE_NAME,
            SITE_DESC: settings.SITE_DESC,}
  • 在 settings.py 中 TEMPLATE的文本處理器中加入
    blog.views.global_setting,

至此,這種方法也不需要在render 或 render_to_response 中指明 context 或 RequestContext 就可以直接在HTML模板中利用模板變量來進行渲染。

相比之下,還是方法2中較簡單。

Django中全局Context處理器