Django 使用全局变量


1、settings.py 中设置变量

2、存放到数据库

 

如何在模板中直接使用全局变量

转自:https://oomake.com/question/62799

1、使用中间件

如果这是您希望获得的每个请求的值,模板,使用context processor更合适。 就是这样:

  1. 在您的应用目录中创建一个context_processors.py文件。假设我想在每种情况下都具有ADMIN_PREFIX_VALUE值:
    from django.conf import settings # import the settings file def admin_media(request): # return the value you want as a dictionnary. you may add multiple values in there. return {'ADMIN_MEDIA_URL': settings.ADMIN_MEDIA_PREFIX} 
  2. 将你的上下文处理器添加到你的settings.py文件中:
    TEMPLATES = [{
        # whatever comes before
        'OPTIONS': { 'context_processors': [ # whatever comes before "your_app.context_processors.admin_media", ], } }] 
  3. 在您的视图中使用RequestContext以在模板中添加上下文处理器。 render shortcut会自动执行此操作:
    from django.shortcuts import render def my_view(request): return render(request, "index.html") 
  4. 最后,在您的模板中:
    ...
    <a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a> ..

 

2、自定义模板标签

 

@register.tag
def value_from_settings(parser, token):
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, var = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
    return ValueFromSettings(var)
class ValueFromSettings(template.Node):
    def __init__(self, var):
        self.arg = template.Variable(var)
    def render(self, context):        
        return settings.__getattr__(str(self.arg))

然后你可以使用:

{% value_from_settings "FQDN" %}

可以在任何页面上打印,而无需跳过上下文处理器环节。

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



作者:lanzhiheng
链接:https://www.jianshu.com/p/d90469a527d4
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM