Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable context between two blocks in Django templates?

I have two blocks that call the same method with same variables. I want to call the method only once, but the result is then outsite the scope of the block tags. I've tried calling this method in the parent template header.html and with a with tag, but nothing seems to work.

This is the layout:

{% extends "header.html" %}

{% load navigation_tags %}

{% block header %}
    {% get_section site=site as section %}
    {% include "foobar.html" with section=section %}
{% endblock header %}

{% block navigation %}
    <nav>
        <div class="container">
            {% get_section site=site as section %}
            {% navigation section.slug %}
        </div>
    </nav>
{% endblock navigation %}

navigation_tags.py

@register.assignment_tag
def get_parent_section(site):
    if site.id == settings.FOOBAR_SITE_ID:
        section = Section.objects.get(id=settings.FOOBAR_SECTION_ID)
    else:
        # This is also a section instance.
        return site.default_section
like image 374
Saša Kalaba Avatar asked Jul 16 '18 12:07

Saša Kalaba


People also ask

What is context variable in Django?

A context is a variable name -> variable value mapping that is passed to a template. Context processors let you specify a number of variables that get set in each context automatically – without you having to specify the variables in each render() call.

What does {% %} mean in Django?

{% %} and {{ }} are part of Django templating language. They are used to pass the variables from views to template. {% %} is basically used when you have an expression and are called tags while {{ }} is used to simply access the variable.

What {{ name }} means in a Django template?

What does {{ name }} this mean in Django Templates? {{ name }} will be the output. It will be displayed as name in HTML. The name will be replaced with values of Python variable.

What is {% block content %} in Django?

Introducing {% block %} The block tag is used to define a block that can be overridden by child templates. In other words, when you define a block in the base template, you're saying that this area will be populated with content from a different, child template file.


1 Answers

As mentioned by 2pacho in another answer and Fernando Cezar in a comment, the easiest way to share values between different sections is to set it in the template context. If you are using the render shortcut function, you can pass a dict as the context parameter to add a value to the rendering context of the template. That would be a good place to add it and this would be the easiest place to put it.

return render(request, 'template.html', {'section': get_parent_section(site)})

However, if for some reason, you can't include it in the context, you can use a decorator to add memoization to your function, so that it will cache the computation results and return it immediately when called with the same parameters. You can use functools.lru_cache to do so, or it's Django backport at django.utils.lru_cache.lru_cache if you are using Python 2.x.

@register.assignment_tag
@functools.lru_cache()
def get_parent_section(site):
    if site.id == settings.FOOBAR_SITE_ID:
        section = Section.objects.get(id=settings.FOOBAR_SECTION_ID)
    else:
        # This is also a section instance.
        return site.default_section
like image 83
JSTL Avatar answered Nov 13 '22 05:11

JSTL