Шаблон, используемый несколькими приложениями, требует определенной переменной

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

<a href="{% url 'blog:blog-detail' user_blog %}">My blog</a>

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

В таких случаях вопрос обычно звучит так: "Как сделать переменную доступной для всех шаблонов?" и поэтому мы перенаправляемся к процессорам контекста шаблонов.


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

user_blog = self.request.user.blog
return {'user_blog': user_blog}

потому что, как отмечает Виллем Ван Онсем

Контекстный процессор только передает дополнительные переменные движку рендеринга шаблона, поэтому он возвращает словарь и не принимает никаких параметров (кроме запроса).

Что мы делаем в таких случаях?

В таком случае вам действительно не нужно использовать Template Context Processors.

Вы можете просто сделать следующее в шаблоне

<a href="{% url 'blog:blog-detail' request.user.blog %}">>My blog</a>

Необходимо проверить, существует ли request.user.blog или нет.

Контекстный процессор действительно имел доступ к объекту запроса:

# context_processors.py
def getBlog(request):
    return { 'user_blog': request.user.blog }

Но! request.user уже доступен изнутри шаблона, поэтому вам не нужен контекстный процессор.


Но если request.user -> blog не является прямым соединением, вы можете сделать что-то вроде:

  • Примечание: Больше для того, чтобы показать, что это возможно
# context_processors.py
def getBlog(request):
    from myproject.thing.models import Blog
    return { 'user_blog': Blog.objects.filter(user=request.user).first() }

Более эффективный путь (чтобы не обращаться к БД постоянно при каждом запросе) - это добавить кэш:

# context_processors.py
def getBlog(request):

    from django.core.cache import cache

    cachedname = 'UserBlog:{0}'.format(request.user.username)
    cachedData = cache.get(cachedname)

    if cachedData:
        # in cache (yay!)
        return { 'user_blog': cachedData }

    else:
        # not in cache (boo!) 

        from myproject.thing.models import Blog
        user_blog = Blog.objects.filter(user=request.user).first()

        cache.set(cachedname, user_blog, 600) # 10 minute cache

        return { 'user_blog': user_blog }
Вернуться на верх