When one uses a template, used by various apps, that requires a specific variable
<a href="{% url 'blog:blog-detail' user_blog %}">My blog</a>
we want to ensure that the template will always be aware of the variable user_blog
. Also, we don't want to hammer the logic in every view.
In such cases, the question popping up is usually within the lines of "How to make a variable available to all templates?" and so we are redirected to Template context processors.
Since what we want is dependent on a user instance, we wouldn't be able to use a context processor for something like this
user_blog = self.request.user.blog
return {'user_blog': user_blog}
because, as noted by Willem Van Onsem
A contextprocessor only passes extra variables to the template render engine, so it returns a dictionary, and does not take any parameters (except for the request).
What do we then do in such cases?
CodePudding user response:
In such case you don't really need to use Template Context Processors.
You can simply do the following in the template
<a href="{% url 'blog:blog-detail' request.user.blog %}">>My blog</a>
Needless to say you ought to check if request.user.blog
exists or not.
CodePudding user response:
A context processor actually had access to the request object:
# context_processors.py
def getBlog(request):
return { 'user_blog': request.user.blog }
But! request.user is already available from inside the template, so you don't need a context processor.
But if request.user -> blog isn't a direct connection you could do something like:
- Note: More-so just showing it's possible
# context_processors.py
def getBlog(request):
from myproject.thing.models import Blog
return { 'user_blog': Blog.objects.filter(user=request.user).first() }
The better route (so you're not always hitting the DB on every request) is to add a cache:
# 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 }