8
votes

Using Django templates in Google App Engine (on Python), is it possible to compare a template variable to an integer in an {% if %} block?

views.py:

class MyHandler(webapp.RequestHandler):
    def get(self):
        foo_list = db.GqlQuery(...)
        ...
        template_values['foos'] = foo_list
        template_values['foo_count'] = len(foo_list)
        handler.response.out.write(template.render(...))

My template:

{% if foo_count == 1 %}
     There is one foo.
{% endif %}

This blows up with 'if' statement improperly formatted.

What I was attempting to do in my template was build a simple if/elif/else tree to be grammatically correct to be able to state

#foo_count == 0:
There are no foos.

#foo_count == 1:
There is one foo.

#else:
There are {{ foos|length }} foos.

Browsing the Django template documents (this link provided in the GAE documentation appears to be for versions of Django far newer than what is supported on GAE), it appears as if I can only actually use boolean operators (if in fact boolean operators are supported in this older version of Django) with strings or other template variables.

Is it not possible to compare variables to integers or non-strings with Django templates?

I'm sure there is an easy way to workaround this - built up the message string on the Python side rather than within the template - but this seems like such a simple operation you ought to be able to handle in a template.

It sounds like I should be switching to a more advanced templating engine, but as I am new to Django (templates or any part of it), I'd just like some confirmation first.

5
The webapp template system comes from Django 0.96; the documentation is at djangoproject.com/documentation/0.96 Newer versions of Django are available on App Engine, but it might be tricky to get them loaded when using webapp rather than the whole django framework.Wooble

5 Answers

5
votes

right:

{% if foo_list == 1 %}

wrong:

{% if foo_list== 1 %}
4
votes

You are most probably using Django 0.96:

The App Engine Python environment includes three versions of Django: 0.96, 1.0.2, and 1.1. Django 0.96 is included with the App Engine SDK, and is the version that gets imported by default when an app imports the django package.

Source: http://code.google.com/appengine/docs/python/tools/libraries.html#Django

As xyld has said, you must use the ifequal templatetag, because boolean operators were included only in version 1.2, that is currently in beta.

The documentation for version 0.96 can be found here or you can also use version 1.1:

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

from google.appengine.dist import use_library
use_library('django', '1.1')

Of course, you can always download the entire Django project, and include it in your application's top level directory. Some tips on how to do that can be found in this article.

EDIT: Since the ifequal is not suited for integers, you can pass additional variables to your template.

class MyHandler(webapp.RequestHandler):
    def get(self):
        foo_list = db.GqlQuery(...)
        ...
        template_values['foos'] = foo_list
        template_values['foo_count'] = len(foo_list)
        template_values['one_foo'] = len(foo_list) == 1
        handler.response.out.write(template.render(...))

and in the template:

{% if one_foo %}
    You have one foo.
{% endif %}

or:

{% if foo_list %}
    You have {{ foo_count }} foo{{foo_count|pluralize}}.
{% else %}
    You have no foos
{% endif %}
2
votes

if tags may also use the operators ==, !=, <, >, <=, >=, in, not in, is, and is not which works.

(Django 3.0)

{%if number > 1 %}

 #stuff 

{%elif number < 1 %}

 #stuff

{%elif number == 0 %}

 #stuff

{%endif%}

Comparison in Templates Django Official Doc

1
votes

You're using a template variable named foo_list:

{% if foo_list == 1 %}

but there's no such variable in the template your code builds, only foo and foo_count.

1
votes

Django 1.2 allows for == operators in the {% if %} tag. If you need to compare two integers or other items, you can always use {% ifequal a b %}...{% endifequal %} in older versions of Django.

My guess is that you are reading the Development docs (django 1.2), but using django 1.1 or 1.1.1

However, if you need to do {{ foo|length }} and compare the output of that template tag + filter, you won't be able to. You'll need to fix your view logic to calculate that for you so you can use it in the template.

Also, depending on how you are using the list, you can look into for...empty:

http://docs.djangoproject.com/en/dev/ref/templates/builtins/#for-empty