Reputation: 930
I am trying to get the following working.
The count loop needs to loop through for all values, and there may not be a user associated with each count, but the count value i
needs to be used in each loop to pass to the JavaScript.
python part:
users = {}
users[1]={}
users[1][id]=...
users[1][email]=...
...
count=[1,2,3,4,5,6,7,8,9,10]
Django template part:
{% for i in count %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1
email:{% if users.i.email %}'{{users.i.email}}'{% else %}null{% endif%}
{% endfor %}
This returns nothing for email.
When I substitute the number 1
for i
in {% if user.i.email %}
email returns the users email address.
I'm using the data in JavaScript, so it needs to be implicitly null if it doesn't exist.
I can't seem to get Django to recognize the i
variable as a variable instead of the value i.
using []
doesn't work, as it throws an invalid syntax error
email:{% if users.[i].email %}'{{users.[i].email}}'{% else %}null{% endif%}
I have tried using "with
" statement
{% for i in count %}{% with current_user=users.i %}...
and then using current_user.email
, but returned nothing
Have also tried
{% for i in count %}{% with j=i.value %}...
just in case it would work, and then trying to use j
, but same result.
I have thought about creating an inner for loop that loops over the user object and check if i is equal to the key/value, but that seems expensive and not very scalable.
Any ideas how I can force Django to view i
as a variable and use it's value as an index, or any other way get around this?
Thanks
Jayd
*Edit:
I tried the extra for loop, as suggested by Abhi, below.
{% for i in count %}
{% for key, current_user in users.items %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1
email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}
{% endfor %}
{% endfor %}
This sort of works, but now it will repeat do some stuff with the value i
for every value of users. and if I put in an if:
{% for i in count %}
{% for key, current_user in users.items %}
{% if i == key %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1
email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}
{% endif%}
{% endfor %}
{% endfor %}
That ignores the loops when a count doesn't have a particular user.
The only way I can see around this is the have the user loop at each place that I want to use current_user
.
{% for i in count %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1
email:{% for key, current_user in users.items %}{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}{% endfor %}
{% endfor %}
And this seems very expensive to do. Any ideas?
I was thinking of maybe writing a filter that returns the values for users using i
as the key:
{% with current_user=users|getuser:i %}
But I don't know if this will work or I will get the same error, where i
is being passed as the value 'i' instead of a variable name.
I will give it a try so long.
*Edit
This didn't work.
The filter worked using {{}}
returning the object, but it didn't work inside the {% %}
.
Thanks for the input
Upvotes: 6
Views: 7565
Reputation: 69
to make Jayd Code usable with either list or dict, try this
@register.filter(name='dict_value_or_null')
def dict_value_or_null(dict, key):
try:
return dict[key]
except:
return 'null'
Upvotes: 1
Reputation: 930
I have come up with the following as a work around:
This is the filter code:
@register.filter(name='dict_value_or_null')
def dict_value_or_null(dict, key):
if key in dict:
return dict[key]
else:
return 'null'
Here is the template code
{% for i in count %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1
email:'{{users|dict_value_or_null:i|dict_value_or_null:'email'}}'
{% endfor %}
This works well, so I suppose that have my solution. But I still think this all could have been much easier if there was a way in the template system to force values inside {% %} to be treated as variables, instead of literals.
Is there a way to do this?
Thanks for the input
Upvotes: 1
Reputation: 599470
As Joe says in his comment, a dictionary is clearly the wrong data structure for the outer container. You should be using a list.
users = []
user = {'id':..., 'email': ...}
users.append(user)
...
{% for user in users %}
{{ user.email }}
{% endfor %}
If you need the number of each user within the loop, you can use {{ forloop.counter }}
.
Upvotes: 9
Reputation: 61
Try this:
{% for key,val in user.items %}
ID is {{ val.id }} and Email is {{ val.email }}
{% endfor %}
Upvotes: 1