【问题标题】:Django variable in base.htmlbase.html 中的 Django 变量
【发布时间】:2014-01-30 12:04:24
【问题描述】:

base.html 用作所有其他页面的基本模板。 base.html 有导航栏,在导航栏中,我想显示用户收到的消息数量。因此,我需要在base.html 中有一个类似{{number_of_messages}} 的变量。

但是,我应该如何将这个变量传递给它?每个模板都扩展 base.html 并由函数呈现。我不认为在所有函数中返回 number_of_messages 是一个好方法。有没有更好的方法来实现这一点?如何将此变量传递给所有模板?

【问题讨论】:

  • 你看过 django 模板上下文处理器吗?也许最短的答案是创建您自己的上下文处理器并将其放入您的设置文件中的TEMPLATE_CONTEXT_PROCESSORS。我的 cmets 应该是一个答案吗?参考:docs.djangoproject.com/en/dev/ref/templates/api/…
  • 嗨,Yeo,我没看过。是否可以通过使用包含标签并将包含标签放在 base.html 中来实现这一目标?
  • 我认为根据您的主要问题,模板中的变量称为contextinclude 标签,做不同的事情,但当然你可以在包含的模板中传递上下文,如{% include "name_snippet.html" with person="Jane" greeting="Hello" %}。但是您仍然需要正确的上下文...docs.djangoproject.com/en/dev/ref/templates/builtins/#include
  • 希望您设法解决了您的问题。如果您仍有问题,请告诉我:-)
  • 谢谢。我觉得这本书很好,我将继续完成它:b-list.org/weblog/2006/jun/14/…

标签: python django


【解决方案1】:

你可以使用标签。

#myproject/myproject/templatetags/tags.py

from django import template

register = template.Library()

@register.simple_tag
def number_of_messages(request):
    return _number

在你的 Base.html 中

{% load tags %}
    {% number_of_messages request %}

【讨论】:

  • 谢谢!另一个问题,tags.py 应该在模板文件夹下吗?
  • 对不起。 tags.py 应该在 templatetags 下。
【解决方案2】:

看看:
https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

只要:

  • 您在视图中使用render 快捷方式(或者注意使用RequestContext 来呈现您的响应)
  • 在您的TEMPLATE_CONTEXT_PROCESSORS 设置中有django.contrib.auth.context_processors.auth (as it is by default)

...那么您的模板中有当前请求的User(或AnonymousUser)实例{{ user }}...我猜您可以从那里直接访问消息数?

或者您可能正在使用 Django 的messages framework

这带有它自己的上下文处理器(只要您使用renderRequestContext)将使{{ messages }} 变量(包含当前用户的消息)在您的模板中可用。对于“消息数量”,您可以执行 {{ messages|length }}

如果这些内置选项都不能满足您的需求,您也可以:

  • make your own template context processor 将为每个请求运行并为所有模板提供额外的变量(当使用RequestContext呈现时)

  • make your own template tag 只能在需要的地方使用...当然,如果在您的 base.html 中使用它并且所有模板都继承自 base.html,那么它仍然会在每个页面上运行。

【讨论】:

  • 很好的答案!对我有很大帮助。谢谢!
【解决方案3】:

我发现在 django 中将变量传递给基本模板的最简单步骤是添加一个 context_processor.py 文件,如下所示:

在您的应用中创建 context_processors.py 并声明您的变量,例如:

# context_processors.py
def message_processor(request):
    if request.user.is_authenticated:
        no_msgs = request.user.profile.msgs
    else:
        no_msgs = 0
    return {
        'messages' : no_msgs
    }

然后在 settings.py 文件中注册您的进程或在 TEMPLATES 下:

TEMPLATES = [
    {
        ...
            'context_processors': [
                ...
                # custom
                'appname.context_processors.message_processor',
            ],
        },
    },
]

然后您就可以在应用中的任何位置获取该变量,如下所示:

{{ messages }}

【讨论】:

  • 这个答案是纯金。我爱你乔希
【解决方案4】:

如果您真的希望在所有视图中使用变量,那么自定义模板上下文处理器可能是最好的选择。

https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext

如果您只想在某些视图中使用变量,那么您可以让这些视图调用一个填充通用变量的通用函数,如下所示:

def some_view(request):
    params = _common_params(request)
    params.update({
        # params specific to .some_view
    })
    return render_to_response('path/to/template, params)

或者像这样创建一个自定义装饰器:

from functools import wraps

def render_with_params():
    def _inner(view_method):
        def _decorator(request, *args, **kwargs):
            params = _common_params(request)
            (template_path, view_params) = view_method(request, *args, **kwargs)
            params.update(view_params)
            return render_to_response(template_path, params, context_instance=RequestContext(request))
        return wraps(view_method)(_decorator)
    return _inner

@render_with_params()
def some_view(request):
    params = { ... }
    return ('path/to/template', params)

【讨论】:

  • 谢谢!我认为在我的情况下,我应该使用上下文处理器,因为我需要在所有模板中都有变量。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 2019-05-15
  • 2021-02-05
  • 2017-12-27
  • 2012-09-27
  • 1970-01-01
相关资源
最近更新 更多