Шаблон, используемый несколькими приложениями, требует определенной переменной
Когда используется шаблон, используемый различными приложениями, который требует определенной переменной
<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 }