We can set the value of a variable in the Django template using with tag. This will output the below content. One downside of this approach is that we have to write the lines where we are accessing the variable inside with and endwith block. Using with is useful when using a costly variable multiple times.
There are tricks like the one described by John; however, Django's template language by design does not support setting a variable (see the "Philosophy" box in Django documentation for templates). Because of this, the recommended way to change any variable is via touching the Python code.
You can use the with
template tag.
{% with name="World" %}
<html>
<div>Hello {{name}}!</div>
</html>
{% endwith %}
The app should contain a templatetags
directory, at the same level as models.py
, views.py
, etc. If this doesn’t already exist, create it - don’t forget the __init__.py
file to ensure the directory is treated as a Python package.
define_action.py
inside of the templatetags directory with the following code:from django import template
register = template.Library()
@register.simple_tag
def define(val=None):
return val
Note: Development server won’t automatically restart. After adding the templatetags
module, you will need to restart your server before you can use the tags or filters in templates.
{% load define_action %}
{% if item %}
{% define "Edit" as action %}
{% else %}
{% define "Create" as action %}
{% endif %}
Would you like to {{action}} this item?
An alternative way that doesn't require that you put everything in the "with" block is to create a custom tag that adds a new variable to the context. As in:
class SetVarNode(template.Node):
def __init__(self, new_val, var_name):
self.new_val = new_val
self.var_name = var_name
def render(self, context):
context[self.var_name] = self.new_val
return ''
import re
@register.tag
def setvar(parser,token):
# This version uses a regular expression to parse tag contents.
try:
# Splitting by None == splitting by spaces.
tag_name, arg = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
m = re.search(r'(.*?) as (\w+)', arg)
if not m:
raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
new_val, var_name = m.groups()
if not (new_val[0] == new_val[-1] and new_val[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
return SetVarNode(new_val[1:-1], var_name)
This will allow you to write something like this in your template:
{% setvar "a string" as new_template_var %}
Note that most of this was taken from here
There are tricks like the one described by John; however, Django's template language by design does not support setting a variable (see the "Philosophy" box in Django documentation for templates).
Because of this, the recommended way to change any variable is via touching the Python code.
The best solution for this is to write a custom assignment_tag
. This solution is more clean than using a with
tag because it achieves a very clear separation between logic and styling.
Start by creating a template tag file (eg. appname/templatetags/hello_world.py
):
from django import template
register = template.Library()
@register.simple_tag
def get_addressee():
return "World"
Now you may use the get_addressee
template tag in your templates:
{% load hello_world %}
{% get_addressee as addressee %}
<html>
<body>
<h1>hello {{addressee}}</h1>
</body>
</html>
Perhaps the default
template filter wasn't an option back in 2009...
<html>
<div>Hello {{name|default:"World"}}!</div>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With