Переменная Django в base.html

base.html используется в качестве базового шаблона для всех других страниц. base.html имеет панель навигации и на панели навигации, я хочу показать количество сообщений, полученных пользователем. Таким образом, мне нужно иметь переменную типа {{number_of_messages}} в base.html.

Однако как передать эту переменную? Каждый шаблон расширяет base.html и визуализируется функцией. Я не думаю, что возвращение number_of_messages во все функции - это хороший способ. Есть ли лучший способ реализовать это? Как передать эту переменную всем шаблонам?

Ответ 1

Посмотрите:
https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

Пока:

  • вы используете ярлык render в своем представлении (или иначе позаботитесь использовать RequestContext, чтобы отобразить ответ)
  • есть django.contrib.auth.context_processors.auth в настройке TEMPLATE_CONTEXT_PROCESSORS (как это указано по умолчанию)

... тогда у вас есть текущий экземпляр User (или AnonymousUser), доступный в вашем шаблоне, как {{ user }}... Я предполагаю, что оттуда вы сможете получить доступ к числу сообщений напрямую?

Или, возможно, вы используете Django рамки сообщений?

Он поставляется с собственным процессором контекста, который (пока вы используете render или RequestContext) будет делать {{ messages }} var (содержащий сообщения для текущего пользователя), доступные в ваших шаблонах. Для "количества сообщений" вы можете сделать {{ messages|length }}

Если ни один из этих встроенных опций не предоставляет то, что вам нужно, вы можете:

Ответ 2

Вы можете использовать теги.

#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 %}

Ответ 3

Если вы хотите, чтобы переменная действительно находилась во всех представлениях, возможно, лучший вариант для контекстного процессора шаблонов.

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)