counter in jinja2 flask - python

I want to make a counter
this simple code not working...
{% set count = 1 %}
{% for i in [1,2,3,4,5] %}
{% set count = count + 1 %}
{% endfor %}
<h2>found {{count}}<h2>
the result is 1
i see you can use this How to increment a variable on a for loop in jinja template? but this is not work for me

If you're using Flask and Jinja2, you can use the built in filter length.
{% set my_list = [1,2,3,4,5] %}
{% for i in my_list %}
...
{% endfor %}
<h2>found {{my_list|length}}<h2>
If that doesn't do exactly what you want, you can also expose custom filter or functions from your Flask app when it is initialized by using add_template_filter() or add_template_global()

There are situations where it's more appropriate to do the counting prior to template rendering, passing the count in to the template. You might be looking at one of those. The Jinja2 template "language" is not a full, turing-complete programming language.

Related

Extracting values from a dict - flask and jinja

In my template I have
<p>{% for dict_item in MySQL_Dict %}
{% for key, value in dict_item.items() %}
{{value}}
{% endfor %}
{% endfor %}</p>
Which outputs 43.8934276 -103.3690243 47.052060 -91.639868 How do I keep values i.e. the coordinates together AND have them separated by a comma? Is this possible?
The easiest way is to format it on back-end and pass it the jinja in the way you want. In fact its better to put complex logic on the back-end not the front-end performs better and in jinja's case you don't have to pass in python methods so it's cleaner... other templating frameworks like tornados include all of pythons base functions so you don't have to pass them in like the example below. Another way to do it is to pass the str.join, len, and range method to jinja e.x join=str.join, len=len, range=range then... and I'm guessing MySQL_Dict is a 2d array, hence the double for loop
<p>
{% for dict_item in MySQL_Dict %} // dict_item == [{}, {}, ...]
{% for i in range(len(dict_item)) %} // dict_item[i] == {some object}
{{",".join(dict_item[i]["latitude"], dict_item[i]["longitude"])}}
{% endfor %}
{% endfor %}
</p>

how to set custom forloop start point in django template

There is a forloop in java where i can tell where to start and where to end:
for(int i=10;i<array.length;i++){
}
but how can i implement this int i=10 in django template? How can i set the starting and ending point on my own?
there is a forloop.first and forloop.last, but they are defined inside the loop and i cannot do something like this?:
{{forloop.first=10}}
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
{{forloop.last=20}}
I read the django doc but this feature seems to be not there
How about using built-in slice filter:
{% for athlete in athlete_list|slice:"10:20" %}
<li>{{ athlete.name }}</li>
{% endfor %}
If you need to make a numeric loop (just like python's range), you need a custom template tag, like this one: http://djangosnippets.org/snippets/1926/
See other range snippets:
http://djangosnippets.org/snippets/1357/
http://djangosnippets.org/snippets/2147/
Also see:
Numeric for loop in Django templates
By the way, this doesn't sound like a job for templates - consider passing a range from the view. And, FYI, there was a proposal to make such tag, but it was rejected because it is trying to lead to programming in the template. - think about it.

Checking if something exists in items of list variable in Django template

I have a list of sections that I pass to a Django template. The sections have different types. I want to say "if there is a section of this type, display this line" in my template, but having an issue. What I'm basically trying to do is this.
{% if s.name == "Social" for s in sections %}
Hello Social!
{% endif %}
But of course that's not working. Any idea how to basically in one line loop through the items in a list and do an if statement?
ADDITIONAL INFO: I could potentially have multiple "Social" sections. What I'm trying to do in the template is say "if there are any social sections, display this div. If not, don't display the div." But I dont want the div to repeat, which is what would happen with the above code.
Ideally what you would do is create a list that the template gets as such:
l = [s.name for s in sections]
And in the template, use:
{% if 'Social' in l %}
You're trying to put more logic into a template than they are meant to have. Templates should use as little logic as possible, while the logic should be in the code that fills the template.
You can't use list comprehensions in templates:
{% for s in sections %}
{% if s.name == 'Social' %}
Hello Social!
{% endif %} {# closing if body #}
{% endfor %} {# closing for body #}
{% if sections.0.name == "Social" %}
Hello Social!
{% endif %}

Django template iterating over list

I have a list created in Django view:
list = [ elem1, elem2, ..., elemN ]
The list is variable length: it can contain 0-6 elements. I want to iterate over the list in the template, but I would like the loop to run always 6 times, yielding None or empty string for non-existing elements.
I tried something like this:
{% for i in "0123456" %}
{{ list.i }}
{% endfor %}
but this obviously doesn't work. I know I could do this in the view, but I would like to have this in the template. Is is possible?
You can add an if statement checking if it is your 6th time through the loop.
{% for item in someList %}
{% if forloop.counter <= 6 %}
{{ item }}
{% endif %}
{% endfor %}
http://docs.djangoproject.com/en/1.3/ref/templates/builtins/#for in the docs.
Of course, if your list is very long then this is not optimal. I would also suggest processing the list in views.py and then passing it to the template. Logic should stay in the views if possible.
This gives you control over the number of loops done. To completely solve your problem you will need some addtional logic but see my note above regarding this.
Check this snippet: Template range filter

How do I access a python list from a django templatetag?

I have created a templatetag that loads a yaml document into a python list. In my template I have {% get_content_set %}, this dumps the raw list data. What I want to be able to do is something like
{% for items in get_content_list %}
<h2>{{items.title}}</h2>
{% endfor %}`
If the list is in a python variable X, then add it to the template context context['X'] = X and then you can do
{% for items in X %}
{{ items.title }}
{% endfor %}
A template tag is designed to render output, so won't provide an iterable list for you to use. But you don't need that as the normal context + for loop are fine.
Since writing complex templatetags is not an easy task (well documented though) i would take {% with %} tag source and adapt it for my needs, so it looks like
{% get_content_list as content %
{% for items in content %}
<h2>{{items.title}}</h2>
{% endfor %}`

Categories