Django use value of template variable as part of another variable name - python

I currently have this for loop inside my template:
{% for i in 1234|make_list %}
I would like to obtain something like this inside loop:
{{ form.answer_{{ i }} }}
I am aware that the above line is not valid (it raises TemplateSyntaxError), but I would like to know if there is any way to use the value of i as part my other variable name.

First, you would need a custom template filter to mimic getattr() functionality, see:
Performing a getattr() style lookup in a django template
Then, you would need add template filter for string concatenation:
{% load getattribute %}
{% for i in 1234|make_list %}
{% with "answer_"|add:i as answer %}
{{ form|getattribute:answer }}
{% endwith %}
{% endfor %}

Related

Assign a value to a variable already declared in the template in django?

I googled but unable to find the solution. Where I went thought some answers like This answer
Some official docs which I went through Trans Tag Built-In Tags
Template View
{% load custom_tags %}
{% for each in content %}
{% with tempID='' %} # It is initially empty string
{% if each.contentID != tempID %}
{% tempID = each.contentID %} # Want to assign new value to tempID
....
..
{% endif %}
{% endwith %}
{% endfor %}
Is there any method to assign with tag variable. I tried custom_tags filters also. Not worked.
Is there any method to assign with tag variable?
Yes, you can simply use the {% with tempID= each.contentID %} which in this case will assign a new value to the variable.
Alternative
Variables in templates are merely used to display values and are not often used in a way in which calculation or reassignment is performed. In such cases though you can solve it by using a Django custom filter. See the example below.
.py file - Assign a value to a variable
#register.filter(name='update_variable')
def update_variable(value):
data = value
return data
.HTML file
{% with "true" as data %}
{% if data == "true" %}
//do somethings
{{update_variable|value_that_you_want}}
{% else %}
//do somethings
{% endif %}
{% endwith %}
Note that when you are using Django filters the variable instance resides in Python and not directly in the Template.

Assign multiple variables in a with statement after returning multiple values from a templatetag

Is there a way to assign multiple variables in a with statement in a django template. I'd like to assign multiple variables in a with statement after returning multiple values from a templatetag
My use case is this:
{% with a,b,c=object|get_abc %}
{{a}}
{{b}}
{{c}}
{% endwith %}
I don't think it's possible without a custom templatetag.
However if your method returns always the same length you can do it more compact like this:
{% with a=var.0 b=var.1 c=var.2 %}
...
{% endwith %}
I'm not sure that this as allowed, however from docs multiple assign is allowed.
But you can assign these 3 variables to 1 variable, which will make it tuple object, which you can easily iterate by its index.
{% with var=object|get_abc %}
{{ var.0 }}
{{ var.1 }}
{{ var.2 }}
{% endwith %}
Its not supported and its not a flaw of Django Template Language that it doesn't do that, its Philosophy as stated in the docs:
Django template system is not simply Python embedded into HTML. This
is by design: the template system is meant to express presentation,
not program logic
What you could do is prepare your data on Python side and return appropriate format which will be easy to access in template, so you could return a dictionary instead and use dotted notation with key name:
{# assuming get_abc returns a dict #}
{% with var=object|get_abc %}
{{ var.key_a }}
{{ var.key_b }}
{{ var.key_c }}
{% endwith %}

Can you declare multiple with variables in a django template?

I know it's not good practice, but is there a way to declare multiple variables in a with statement in a django template.
For example I want to do something like this:
{% with a="a", b="b", c="c" %}
{{a}}
{{b}}
{{c}}
{% endwith %}
Edit
My actual use case is this:
{% with a,b,c=object|get_abc %}
{{a}}
{{b}}
{{c}}
{% endwith %}
Edit 2
New Question for first Edit: Assign multiple variables in a with statement after returning multiple values from a templatetag
The example on the doc page clearly states that you can assign more than one variable, but you wouldn't need those commas:
{% with alpha=1 beta=2 %}
...
{% endwith %}
Reference:
with template tag

'for' statements should use the format 'for x in y': while iterating over value retrieved from dictionary using django template

I have a context dictionary entry objectives that maps objective query objects to a list of tests that belong to that objective. Example code:
objectives = Objective.objects.filter(requirement=requirement)
context_dict["requirements"][requirement] = objectives
for objective in objectives:
tests = Test.objects.filter(objective=objective)
context_dict["objectives"][objective] = tests
In my django html template, I iterate over objectives and display them. I then want to iterate over the tests that belong to these objectives. When I do this:
{% for test in {{ objectives|get_item:objective }} %}
I get a TemplateSyntaxError: 'for' statements should use the format 'for x in y':
In the application/templatetags directory, I have:
from django.template.defaulttags import register
...
#register.filter
def get_item(dictionary, key):
return dictionary.get(key)
If instead I make {{ objectives|get_item:objective }} a JS variable, I see that it does indeed produce a list, which I should be able to iterate over. Of course, I can't mix JS variables and the django template tags, so this is only for debugging:
var tests = {{ objectives|get_item:objective }}
var tests = [<Test: AT399_8_1>, <Test: AT399_8_2>, <Test: AT399_8_3>, <Test: AT399_8_4>, <Test: AT399_8_5> '...(remaining elements truncated)...']
How do I iterate over this list in the django template tag?
You cannot user {{...}} inside the {%...%}
What you can try is changing your filter to an assignment tag and using that value in the loop
#register.assignment_tag
def get_item(dictionary, key):
return dictionary.get(key)
And then in your template use it as
{% get_item objectives objective as tests %}
{% for test in test %}
....
{% endfor %}
Instead of all this if your models are proper with foreign keys I would do something like
{% for objective in requirement.objective_set.all %}
{% for test in objective.test_set.all %}
....
{% endfor %}
{% endfor %}
In my context I would pass only the requirement
You already have an answer, but note that dropping the {{ }} tags and keeping everything else the same would have worked fine.
{% for test in objectives|get_item:objective %}
**This is Right Answer for Using Django if else and for loop **
Note :- We Have to Put Key in " " string (Double quotes) some time produce an error so That is good way bcz i faced that problem whwn i Learned
{% if 'numbers'|length > 0 %}
{% for i in numbers %}
{% if i > 20 %}
{{i}}
{% endif %}
{% endfor %}
{% else %}
Empty
{% endif %}

Modify django templates to check for values in a dict

I have the following Django template.
{% load custom_tags %}
<ul>
{% for key, value in value.items %}
<li> {{ key }}: {{ value }}</li>
{% endfor %}
I need to check for the value and do some modifications.
If the value is True , instead of value I have to print Applied , else if it False I need to print Not Applied.
How to achieve that?
Very simple if-else clause here. Take a look at the django template docs to familiarize yourself with some of the common tags.
{% if value %}
APPLIED
{% else %}
NOT APPLIED
{% endif %}
You asked how to do this as a filter... I'm not sure why, but here is it:
In your app's templatetags directory create a file called my_tags.py or something and make the contents
from django import template
register = template.Library()
#register.filter
def applied(value):
if value:
return 'Applied'
else:
return 'Not applied'
Then in your template make sure to have {% load my_tags %} and use the filter with {{ value|applied }}

Categories

Resources