63


I am trying to pass in url parameters to a django template like this...

response = render_to_string('persistConTemplate.html', request.GET)

This the calling line from my views.py file. persistConTemplate.html is the name of my template and request.GET is the dictionary that contains the url parameters.

In the template I try to use one of the parameters like this...

{% for item in (numItems) %}

  item {{item}}

{% endfor %}

numItems is one of the url parameters that I am sending in my request like this...

http:/someDomain/persistentConTest.html/?numItems=12

When I try the for loop above, I get an output like this....

image 1 image 2

I am expecting and would like to see the word image printed 12 times...

image 1 image 2 image 3 image 4 image 5 image 6 image 7 image 8 image 9 image 10 image 11 image 12

Can anyone please tell me what I am going wrong?

Adam Wagner
  • 15,469
  • 7
  • 52
  • 66
user479808
  • 643
  • 1
  • 5
  • 6

8 Answers8

144

you can coerce a str to an int using the add filter

{% for item in numItems|add:"0" %}

https://docs.djangoproject.com/en/dev/ref/templates/builtins/#add

to coerce int to str just use slugify

{{ some_int|slugify }}

EDIT: that said, I agree with the others that normally you should do this in the view - use these tricks only when the alternatives are much worse.

aliteralmind
  • 19,847
  • 17
  • 77
  • 108
scytale
  • 12,346
  • 3
  • 32
  • 46
  • 1
    Thank you. I got a headache working with forms. The catch was in "foreignkey" field. When loaded from DB "form..value" contains integers. But after submiting "form..value" are strings.... TADÁ! – darkless Sep 02 '13 at 17:28
  • instead of doing list comprehensions on ids... neat. so simple. – benzkji Jul 29 '14 at 10:03
  • It seems `slugify` works for me. Now I am just wondering what's the meaning of that word. Slugify is not in my vocabulary nor in my dictionary. – kasperd May 28 '15 at 07:44
  • On django 1.8, **add:"0"** worked for me, **slugify** didn't. – Cherif KAOUA Dec 04 '15 at 09:21
  • After using `floatformat` and `intcomma`, `add` is just appending a `'0'` – gdvalderrama Jan 09 '18 at 13:23
39

I like making a custom filter:

# templatetags/tag_library.py

from django import template

register = template.Library()

@register.filter()
def to_int(value):
    return int(value)

Usage:

{% load tag_library %}
{{ value|to_int }}

It is for cases where this cannot be easily done in view.

clime
  • 8,695
  • 10
  • 61
  • 82
10

Yes, the place for this is in the view.

I feel like the above example won't work -- you can't iterate over an integer.

numItems = request.GET.get('numItems')

if numItems:
   numItems = range(1, int(numItems)+1)

return direct_to_template(request, "mytemplate.html", {'numItems': numItems})


{% for item in numItems %}
 {{ item }}
{% endfor %}
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Thank you for your response but I get the same result when I try it this way.... image 1 image 2 – user479808 Jan 28 '11 at 19:14
  • Can you post your code? This code works. I noticed a slight mistake where I wrote `range(1, int(range)+1)` which should be `range(1, int(numItems)+1)` (this should have thrown an exception if you tried to run it anyways. If 'numItems' is passed into GET, create a list of integers from 1 to `numItems`, and iterate over them in the template. – Yuji 'Tomita' Tomita Jan 28 '11 at 19:18
  • Traceback (most recent call last): File "views.py", line 29, in ? pprint(persistentConTestPage(req)) File "views.py", line 18, in persistentConTestPage return direct_to_template(request, "persistConTemplate.html", {'numItems': numItems}) File "/usr/lib/python2.4/site-packages/django/views/generic/simple.py", line 16, in direct_to_template c = RequestContext(request, dictionary) – user479808 Jan 28 '11 at 20:25
  • File "/usr/lib/python2.4/site-packages/django/template/context.py", line 107, in __init__ self.update(processor(request)) File "/usr/lib/python2.4/site-packages/django/core/context_processors.py", line 34, in debug if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS: AttributeError: 'mockHttpRequest' object has no attribute 'META' – user479808 Jan 28 '11 at 20:28
  • I am getting the error above when I try to compile locally. I think that this may be why I am seeing the same result as before. I think my views.py file is not getting compiled... – user479808 Jan 28 '11 at 20:29
  • I've gone ahead and tested this in a live environment: if you literally copy and paste this code (importing direct_to_template -- point is you can use whichever form of httpresponse you wish), define a mytemplate.html, and load it you will get the results you are looking for. Sorry I can't help you with that error. – Yuji 'Tomita' Tomita Jan 28 '11 at 20:31
  • OK thank you Yuji so very much for all your help. I will see if I can get it working and let you know how it goes. -John – user479808 Jan 28 '11 at 20:47
  • OK so I finally figured out what the trouble is... When you call request.GET.get you have to supply a default value like this... request.GET.get(numItems, 10) Otherwise you get an non type exception. Now the code you supplied above is working for me. Thank you so so much for working with me... – user479808 Jan 28 '11 at 21:45
  • Ah, glad you got it working! I'm confused why request.GET.get('numItems') would cause a problem, since {}.get will return None if the key fails, and django templates silently fail something like iterating over None. – Yuji 'Tomita' Tomita Jan 28 '11 at 21:54
  • Well, I think it's because I am so new at this. I was compiling it locally and not supplying a value for the parameter like the URL would when you pass it in from the response object. Therefore it was trying to supply a default value which was not present and I was getting a NoneType error. Also it his just for those who try this after me if any one hits this tread for a similar reason, I am using render_to_string instead of direct_to_template. – user479808 Jan 28 '11 at 22:04
10

The easiest way to do this is using inbuilt floatformat filter.

For Integer

{{ value|floatformat:"0" }}

For float value with 2 precision

{{ value|floatformat:"2" }}

It will also round to nearest value. for more details, you can check https://docs.djangoproject.com/en/1.10/ref/templates/builtins/#floatformat.

Akash
  • 559
  • 6
  • 17
2

You should add some code to your view to unpack the GET params and convert them to the values you want. Even if numItems were an integer, the syntax you're showing wouldn't give you the output you want.

Try this:

ctx = dict(request.GET)
ctx['numItems'] = int(ctx['numItems'])
response = render_to_string('persistConTemplate.html', ctx)
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
1

In my case one of the items was a string and you can not compare a string to an integer so I had to coerce the string into an integer see below

{% if questions.correct_answer|add:"0" == answers.id %}
    <span>Correct</span>
{% endif %}
cirsam
  • 11
  • 3
0

You can do like that: if "select" tag used.

{% if i.0|stringformat:'s' == request.GET.status %} selected {% endif %}
Shaiful Islam
  • 335
  • 2
  • 12
-1

My solution is kind of a hack and very specific..

In the template I want to compare a percentage with 0.9, and it never reaches 1, but all the values are considered string in the template, and no way to convert string to float.

So I did this:

{% if "0.9" in value %}
...
{% else %}
...
{% endif %}

If I want to detect some value is beyond 0.8, I must do:

{% if ("0.9" in value) or ("0.8" in value) %}
...
{% else %}
...
{% endif %}

This is a hack, but suffice in my case. I hope it could help others.

WesternGun
  • 11,303
  • 6
  • 88
  • 157