Home > Blockchain >  Template used by multiple apps requires a specific variable
Template used by multiple apps requires a specific variable

Time:10-14

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 }
  • Related