1. 程式人生 > >Django 設定template的全域性變數

Django 設定template的全域性變數

相信許多Web開發者一定有那麼一個需求,需要在所有的頁面上面顯示同樣的後臺資料。比如:

1. 使用者資訊: 當一個使用者登陸成功後肯定希望每個頁面都能顯示當前登陸使用者的資訊。
2. 一些由後臺生成的標籤(或者說索引): 使用者可以通過點選標籤進行不同頁面跳轉,但是每個頁面中都會有這些標籤。

這個時候如果在view.py檔案中的每一個方法裡組織對應的資料用於頁面解析,那絕對是十分蛋疼的事情,
這個時候我們就需要把這些資料儲存成全域性變數的形式讓他可以輕鬆渲染到每一個頁面。
Django

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', ], }, }, ]

注意到 OPTIONS.context_processors 裡面有4條資訊,其實每一條資訊都對應一個函式,這裡的原理是設定每一個函式的返回值作為Template的全域性變數
,而最簡單的函式request他是這樣的

from django.template import context_processors.py

def request(request):
    return {'request': request}

它只是簡單地返回一個字典 {‘request’: request} 這就不難理解為什麼在Django的模板系統裡面,所有的Template我們都可以直接訪問request.user來
獲取對應的使用者了吧。由於request被設定成全域性變數,以字典的形式傳到後臺去了。

依樣畫葫蘆,我們也可以編寫個指令碼。:

global_variable.py

from .models import Classification
from taggit.models import Tag

def setting(request):
    classifications = Classification.objects.all()
    tags = Tag.objects.all()
    content = {"classifications": classifications, "tags": tags}
    return content

這只是我blog系統的一小部分程式碼,用於獲取所有的分類,以及所有的Tag標籤,方便搜尋。如果global_variable.py檔案坐落在
BASE_DIR(這個用過Django的朋友應該都知道了吧.這個變數是在settings.py檔案裡面)/blog/page目錄下,則需要設定

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.page.global_variable.setttings'
            ],
        },
    },
]

就OK 了,這樣就可以在templates裡面引用tags, 和classifications變量了.很感謝你有耐心看到這裡,不過希望你能繼續往下看,或許能對你有幫助.

你可能會遇到的坑

下面是我寫的一段程式碼

views.py

def detail(request, id):
    article = get_object_or_404(Article, pk=id)
    template = loader.get_template("page/detail.html")
    context = RequestContext(request, {'article': article})
    return HttpResponse(template.render(context))

但是Django1.9給了我這樣的提示

RemovedInDjango110Warning: render() must be called with a dict, not a RequestContext.說10以後將會丟棄RequestContext

理所當然,我把程式碼改成下面這樣

def detail(request, id):
    article = get_object_or_404(Article, pk=id)
    template = loader.get_template("page/detail.html")
    context = {'article': article}
    return HttpResponse(template.render(context))

接著災難就發生了,雖然說避開了1.9的警告,不過上面的程式碼,沒有把request包裝到RequestContext()裡面解析到模板中去,這就會有一個問題.
所有的settings裡面設定的全域性變數都不起作用了,他根本就不會去解析全域性變數,這個坑,坑了我幾個小時.所以最好的方法是採取Django給我們
的偷懶方法.

from django.shortcuts import render

def detail(request, id):
    article = get_object_or_404(Article, pk=id)
    return render(request, "page/detail.html", context)

因為據說RequestContext()將在1.10被丟棄,考慮到相容性,用它提供的介面最好不過啦.

記得一定要在view的方法裡面把request傳到後臺哦,不然只傳字典的話,全域性變數那便會得不到解析的.