How to set a variable in Django template

So, you need for some reason to set a variable inside a Django template? As you may have figured by now, Django does not implement such a feature. That is, because the logic of setting the variable must go in the view, not in the template. But there are some rare cases when you actually need this.

The way you can solve this is by using a custom Django template tag.

To do this, you create a file called ‘set_var.py’ in your templatetags forlder that contains the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from django import template
 
register = template.Library()
 
class SetVarNode(template.Node):
 
    def __init__(self, var_name, var_value):
        self.var_name = var_name
        self.var_value = var_value
 
    def render(self, context):
        try:
            value = template.Variable(self.var_value).resolve(context)
        except template.VariableDoesNotExist:
            value = ""
        context[self.var_name] = value
        return u""
 
def set_var(parser, token):
    """
        {% set <var_name>  = <var_value> %}
    """
    parts = token.split_contents()
    if len(parts) < 4:
        raise template.TemplateSyntaxError("'set' tag must be of the form:  {% set <var_name>  = <var_value> %}")
    return SetVarNode(parts[1], parts[3])
 
register.tag('set', set_var)

Then to use this in your template, you just do the following:

1
2
3
4
5
6
7
8
9
{% load set_var %}
 
{% set a = 3 %}
{% set b = some_context_variable %}
{% set c = "some string" %}
 
Value of a is {{a}}
Value of b is {{b}}
Value of c is {{c}}

As you can see, you can put in your variables anything that you could normally get inside a Django template: a number, another context variable, a string, etc.

Hope it helped ;)

Comments

26 Responses to “How to set a variable in Django template”
  1. Maidot says:

    Thanks you~ it’s a useful way. :)

  2. François Schiettecatte says:

    Hi

    I have been using this today and it does not work in this case:

    {% set var = 0 %}

    {% for history in page.historyList %}
    {% set var = 1 %}
    {% endfor %}

    {{ var }} # this render 0

    I am assuming this is because the ‘context’ passed to ‘render’ is different in both cases, any ideas on how to get around that?

    Thanks

    • I’ll have to check this on Monday, but I believe is due to the case that the tag will set the varable in the current context, and for’s have their own context. Again, I’ll have to check this in Monday.

      • François Schiettecatte says:

        I expect that is what is going on, I had to work around it. Thanks for the code nonetheless, I used it elsewhere and was able to refactor out hacks I had put in.

        • Nishant says:

          Hi François Schiettecatte,
          I am also facing same issue, do we have any solution now or any other way to do it?

          Thanks in advance!
          Nishant

  3. Johanna says:

    Thanks for the tip ! Saved me a lot of frustration :)

  4. I needed this to make make a nest of unordered lists that could be used by javascript to turn into a ‘tree’ – this helped nicely to determine the level of the tree Thanks !!

  5. matias says:

    hi, i tried setting a var inside a if template tag and dosnt work:

    {% if imagen.imagen.width >= 400 %}
    {% set c = “some string” %}
    {% endif %}

    {{c}}

    this dosnt do anything.

    Any ideas about this?

  6. Kevin Godden says:

    Thanks for the post, very useful. It’s a pity that django doesn’t have support for this out of the box!

  7. dhiru says:

    how to increment or add with another number SET variable

    • The tag code will have to be slightly adjusted so that parts[3] is evaluated before is used as a value. If I’ll have time I’ll implement your idea, shouldn’t be hard …

  8. rkjdid says:

    quick dirty fix for context problems, only dealing with the upper-most context.
    This can be done by changing any context call by context.dicts[0] :

    example :
    context[self.var_name] = value
    becomes :
    context.dicts[0][self.var_name] = value

  9. plex says:

    {% for topic in my_topics %}
    {% set already_follow = true %}
    {% include “topic_item.html”%}
    {% endfor %}

    already_follow will not work in topic_item.html
    What should I do?

  10. foo says:

    Trying this with google app engine, I’ve tried everything, still getting: TemplateSyntaxError: ‘set_var’ is not a valid tag library: Template library set_var not found, tried google.appengine._internal.django.templatetags.set_var

  11. bar says:

    Here’s a snippet of my code,

    {% if forloop.last %}
    {% set flag = 1 %} {%else%} {% set flag = 0%}
    {%endif%}
    .
    .
    {% if flag == 1 %}
    do this
    {% endif %}

    It does not check the condition for if. How do I make it work? Sorry if the question is a bit too naive, I’m new to this.

  12. nitin says:

    {% set a = 3 %}
    {% set b = 3 %}
    {% if a==b %}
    print
    {% else %}
    none
    {% endif %}

    ### why if loop is not working…???

Trackbacks

Check out what others are saying about this post...
  1. […] I installed the set_var template tag. This is because I want to use some of the useful get_language functions that Django makes […]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!