Django 设置template的全局变量

转载自:https://www.jianshu.com/p/d90469a527d4

相信许多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传到后台哦,不然只传字典的话,全局变量那便会得不到解析的.

posted @ 2018-08-28 11:49  赛博坦的bimer  阅读(806)  评论(0编辑  收藏  举报