Django template iterate over list inside request.GET - python

My today's problem is that I've to preserve some url arguments that comes to my view in the request.
Think about the following url:
http://localhost:8000/some-url/?myargument=hello&myargument=world&myargument=whatever
Noticed that every argument in my url has the same key ("myargument")? Keep that in mind
In Django 1.6 if I do {{ request.GET }} in the template I get something like:
<QueryDict: {u'myargument': [u'hello', u'world', u'whatever']}>
To preserve the arguments in the next submit I want to iterate over the request.GET dictionary by creating a hidden field inside the <form> with the key-value pairs, I can do it with this code:
{% for key, value in request.GET.items %}
<input type="hidden" name="{{ key }}" value="{{ value }}">
{% endfor %}
It works with single values, but not in my case because I've a list with the values of the key named "myargument".
Obviously the first thing I tried was to iterate over the value by doing {% for v in value %} when the value is a list, but this only prints out the last item in the "value" list, in this case "whatever".
Anyone had the same problem? How can I solve it? Thanks

in the view:
mydict = dict(request.GET._iterlists())
sent and iterate in the template:
<p>
{{ mydict }}
</p>
<p>
{% for k,v in mydict.iteritems %}
{{ k }}:{% for x in v %}{{ x }},{% endfor %} <br>
{% endfor %}
</p>

Related

django - showing OrderedDict in templatetag

I have a OrderedDict and I need to show its key, value but I am unable to get its value, I have this dict = ([('sainbath', 'thesailor'), ('HELLO', 'WORLD')]), I have tried this
{{object.specifications}}
<ul>
<li>{% for key in object.specifications %}
{{key}}
{%endfor%}
I am getting this output
OrderedDict([('sainbath', 'thesailor'), ('HELLO', 'WORLD')])
sainbath HELLO
I am getting its key only not value, when I tried this
{{object.specifications}}
<ul>
<li>{% for key,value in object.specifications %}
{{key}} : {{value}}
{%endfor%}
it give me error
Need 2 values to unpack in for loop; got 8.
please tell me how can I get value?
1) Use following in template:
{% for key,value in object.specifications.items %}
{{key}}:{{value}}
{% endfor %}
OR
2)If you are rendering a template with the data as OrderedDict, you can use following approach for the same.
return render_to_response('your_template.html',{'data': sorted(your_ordered_dict.iteritems())})
and in Template you can use the same as below:
{% for key, value in data %}
{{key}}:{{value}}
{% endfor %}
Hope it will help you!!

Django template values

I am retrieving model object to my template and I am getting it like this:
value: [{'name_value9': 48}]
When filter the object in the view I am using '.values' like this:
...
name_value.values('name_value' + str(fn))
...
The reason for that is that I have 'name_value1, name_value2, etc... and I need to get to the correct one.
How can I show in the template only the result (value) without the key (name_value9)?
Thanks.
You can print values in your template like this:
{% obj in obj_list %}
{% for key, value in obj.items %}
{{ value }}
{% endfor %}
{% endfor %}

Jinja2 and Json

I have for example a JSON File
{
"Google":{
"Web":"www.web.de",
"Apps":{
"Drive": "DriveLink",
"Dropbox": "DropboxLink"
},
"Google Main":"http://mail.google.com",
"G+":"http://plus.google.com"
},
"Social":{
"Facebook":"http://www.facebook.de",
"G+":"https://plus.google.com",
"Xing":"http://www.xing.de",
"LinkedIn":"http://www.linkedin.com",
"Tumblr":"http://www.tumblr.com"
},
"Fun":{
"Reddit":"http://www.reddit.com"
}
}
As you can see I have under the section Google a Nested Section named Apps
With CherryPy I hand over this JSON Object as following with the name linksList:
#cherrypy.expose
def index(self):
linksFile = open('links.json', 'r')
linksList = json.load(linksFile)
template = jinjaEnv.get_template('index.html')
return template.render(linksList=linksList)
What I want is to render following:
Google
Web (as a link)
Google Main
G+
Apps
Drive
Dropbox
Social
Facebook
G+
Xing
and so on
What I don't understand is to do is to render this nested Objects like "Apps" recursively
The documentation reads:
It is possible to use loops recursively. This is useful if you are
dealing with recursive data such as sitemaps. To use loops recursively
you basically have to add the recursive modifier to the loop
definition and call the loop variable with the new iterable where you
want to recurse.
In your case this would be accomplished with the following:
<ul>
{% for key, value in linksList.items() recursive %}
<li>
{% if value is string %}
{{ key }}
{% else %}
{{ key }}
<ul>{{ loop(value.items()) }}</ul>
{% endif %}
</li>
{% endfor %}
</ul>
My 2 cents, just if someone comes here looking for rendering a JSON using Jinja, and complementing the response from #Ryon Sherman :)
Since JSON may have int values as well as strings, you can use if value is mapping (and flip the if-condition)
If your output must feel like a JSON you can use {{key|indent(width)}} + loop.depth
In my case, the template was for an email and key|indent() didn't work as expected so I ended up using an auxiliar {% for %} loop:
<div>
<code>{
{% for key, value in dic.items() recursive %}
{% if value is mapping %}
<p>
{% for it in range(loop.depth) %} {% endfor %}{{key}}: {
</p>
{{ loop(value.items()) }}
<p>
{% for it in range(loop.depth) %} {% endfor %}}
</p>
{% else %}
<p>
{% for it in range(loop.depth) %} {% endfor %}{{key}}: {{value}},
</p>
{% endif %}
{% endfor %}
}</code>
</div>

My for loop doesn't get the values

Here's what I have:
result = defaultdict(<type 'list'>,
{'USA': [{'username': 'user123', 'first-name': 'John', 'last-name': 'Doe'}],
'Europe': [{'username': 'myname654', 'first-name': 'Peter', 'last-name': 'Johnson'}]
})
Here's the output I want to get
<html>
<body>
<h1> USA </h1>
<p> user123, John Doe</p>
<h1> Europe </h1>
<p> myname654, Peter Johnson</p>
</body>
</html>
I've tried tons of different for loops, but none of them worked.
Here's what I have, but it doesn't work.
{% for item in result %}
<h1> {{ item }} </h1>
<p> {{ result.item.username }} </p>
{% endfor %}
Result is a dictionary. Iterating through a dictionary with for x in mydict just gives the keys, not the values. So you need to do {% for item, value in mydict.items %}.
Secondly, {{ result.item.username }} makes no sense at all. item is a the value of a key into the result dict, but you can't do that sort of indirect lookups in Django templates. However, luckily we have the value in the value variable.
Thirdly, as Kabie points out, each value is actually a single-element list. So you'll need to access the first item in that list, and then the username member of that.
Putting it all together:
{% for item, value in result.items %}
<h1> {{ item }} </h1>
<p> {{ value.0.username }} </p>
{% endfor %}
You are using print to get output in your for loop. This first converts the object to a string. Apparently the objects in this case is some sort of xml/html objects.
From inside the Django template, you don't print. You could try converting the objects to string via a str() call, but in general I have the feeling you are trying to make the templates do something that you shouldn't make templates to in the first place.
Try having a method on the model object that returns the string you want, and inserting that into the template instead.
I think the line:
<p> {{ result.item.username }} </p>
should be:
<p> {{ result.item.0.username }} </p>

Django dictionary in templates: Grab key from another objects attribute

I have a dictionary called number_devices I'm passing to a template, the dictionary keys are the ids of a list of objects I'm also passing to the template (called implementations). I'm iterating over the list of objects and then trying to use the object.id to get a value out of the dict like so:
{% for implementation in implementations %}
{{ number_devices.implementation.id }}
{% endfor %}
Unfortunately number_devices.implementation is evaluated first, then the result.id is evaluated obviously returning and displaying nothing. I can't use parentheses like:
{{ number_devices.(implementation.id) }}
because I get a parse error. How do I get around this annoyance in Django templates?
Thanks for any help!
A workaround could be using the keys from number_devices and check in the for loop if it is equal to the key provided by number_devices.
{% for key in number_devices.keys %}
{% for implementation in implementations %}
{% ifequal key implementation.id %} you got it {% endifequal %}
{% endfor %}
{% endfor %}
Seems a bit ugly, but should work.

Categories