writing the ladder if equality statements in django - django

I know i can do this in django template
ifequal "this"
...//
else
...//
endifequal
but how do i write this
ifequal "this"
..//
elseifequal "this"
...//
else
....
is there a elegant way to achieve this in django ?

Django templates support the Python-like elif tag. For example:
{% if this == True %}
Yes!
{% elif this == False %}
No!
{% else %}
What?
{% endif %}
Source: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#if
The documentation is very easy to find, so I suggest you read up on that.

try this,
{% ifequal p.gender "M" %}
Bloke
{% else %}
Sheila
{% endifequal %}
The ifequal tag determines if two arguments are equal. The arguments can be either
variables or hard-coded strings. If the arguments match, the template engine renders the
code inside the ifequal block. You need to add an endifequal tag to end the block.
https://docs.djangoproject.com/en/1.6/ref/templates/builtins/#ifequal

Related

In a django template I would like to use the for loop.counter0 to index into a list

I have something like the following:
{% for i in "xxxxxxxxx" %}
...
{% if passedInList.*forloop.counter0|add:"1"* %} Do Something {% endif %}
...
{% endfor %}
Obviously the if statement is incorrect. I have been using this method to create index names in forms for quite some time, but have never had to use the for loop counter index in an if statement.
Is this possible? If so, how would I go about doing so?
Thanks!
Try to use a with statement to save the forloop counter in a context variable, like so:
{% with index=forloop.counter %}
{% if passedInList.index %} do something {% endif %}
{% endwith %}
(Also, seems like you can use forloop.counter instead of forloop.counter0|add:"1")

Showing random objects in Django template

In my Django template as I am iterating through a list of objects, I'd like to have one list item say:
<li>Blah</li>
and then another do:
<li>Blah</li>
I see value|random as an option but for some reason this doesn't work:
{% ifequal [1, 2]|random 1 %}
{{ post.title }}
{% else %}
{{ post.title }}
{% endifequal %}
Doing this throws this error:
u'ifequal' takes two arguments
Is there any way to accomplish this? I would think it should be simple but I realize the Django templating language doesn't allow for variable assignments.
Thanks!
You can't put a list directly into the template like that, make_list is what you're after.
make_list returns a list of strings, so this would work.
{% if 12|make_list|random == '1' %}
<li>Blah</li>
{% else %}
<li>Blah</li>
{% endif %}

Django template - set variable in for loop

I am using this code in my templatetags:
http://pastie.org/3530409
And I know for context problem and bad design (that this logic should not be in view) but I need in template solution for this:
{% for tag in page.tagname_list %}
{% ifequal tag "wiki" %}
{% set howto = 1 %}
{% endifequal %}
{% endfor %}
So I can use howto variable latter for my view logic.
Is there any way to do this in view templates, without model modification ?
If answer yes, please provide some solution...
Thanks a lot.
Instead of having to set the variable, you could just do:
{% if "wiki" in page.tagname_list %}
# do your wiki stuff below.
{% endif %}

Django template for loop. Member before

I want to create such loop:
{% for object in objects %}
{% if object.before != object %}
{{ object }} this is different
{% else %}
{{ object }} this is the same
{% endfor %}
Based on https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for I can't. Is there really no simple way to do this? Or I just need to use counter and check for objects[counter-1]?
P.S. .before is theoretical and objects is simple query list. I want to take and do something with the loop member that encountered before current loop member.
Check ifchanged template tag
There is a "simple way" to do this: write a custom template tag. They're really not hard. This would probably do the trick (untested):
#register.simple_tag
def compare_objects(object_list):
comparisons = []
for i in range(1, len(object_list)):
if object_list[i] > object_list[i-1]:
comparisons.append('bigger')
else:
comparisons.append('smaller')
return comparisons
The built-in template tags and filters don't make it easy (as of Django 1.4), but it is possible by using the with tag to cache variables and the add, slugify, and slice filters to generate a new list with only one member.
The following example creates a new list whose sole member is the previous member of the forloop:
{% for item in list %}
{% if not forloop.first %}
{% with forloop.counter0|add:"-1" as previous %}
{% with previous|slugify|add:":"|add:previous as subset %}
{% with list|slice:subset as sublist %}
<p>Current item: {{ item }}</p>
<p>Previous item: {{ sublist.0 }}</p>
{% endwith %}
{% endwith %}
{% endwith %}
{% endif %}
{% endfor %}
This isn't an elegant solution, but the django template system has two faults that make this hack unavoidable for those who don't what to write custom tags:
Django template syntax does not allow nested curly parenthesis. Otherwise, we could do this:
{{ list.{{ forloop.counter|add:-1 }} }}
The lookup operator does not accept values stored using with (and perhaps for good reason)
{% with forloop.counter|add:-1 as index %}
{{ list.index }}
{% endwith %}
This code should work just fine as a django template, as long as object has a property or no-argument method called before, and objects is iterable (and '<' is defined).
{% for object in objects %}
{% if object.before < object %}
this is bigger
{% else %}
this is smaller
{% endfor %}

django 'if' statement improperly formatted

Im getting strangest error in django so far:
'if' statement improperly formatted
Template that raises the error is this:
{% if diff >= 0 %}
<span class="pos">+{{ diff }}
{% else %}
<span class="neg">-{{ diff }}
{% endif %}
</span>
<span>{{ a }}</span>
view that has a and diff in context is this:
def add(request, kaart_id):
if request.is_ajax() and request.method == 'POST':
x = Kaart.objects.get(id=kaart_id)
x.pos += 1
x.save
x = Kaart.objects.get(id=kaart_id)
from django.utils import simplejson
diff = x.pos - x.neg
a = "(+1)"
context = { 'diff':diff, 'a':a }
return render_to_response('sum.html', context, context_instance=RequestContext(request))
It does not matter what equation i use in if, >, >=, ==.. they all raise the same error.
and as far as i can tell its all by the book: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#id5
Alan.
Until Django 1.2 lands you are looking for "Smart If", a Django Template Tag.
A smarter {% if %} tag for django
templates.
While retaining current Django functionality, it also handles
equality,
greater than and less than operators. Some common case examples::
{% if articles|length >= 5 %}...{% endif %}
{% if "ifnotequal tag" != "beautiful" %}...{% endif %}
Arguments and operators must have a space between them, so
{% if 1>2 %} is not a valid smart if tag.
All supported operators are: or, and, in, = (or
==), !=, >, >=, < and <=.
As mentioned, you can't use operators in the {% if %} tag. It accepts only Boolean values (which you can AND, OR and NOT together.)
For simple equality, you can use the {% ifequal val1 val2 %} tag.
The reason is to push the "logic" out of the template and into the model layer. I.e. you should have a method on your model like so:
def positive_diff(self):
return self.diff >= 0
Then call that in your template:
{% if x.positive_diff %} ... {% endif %}
Or, you can set an extra variable in your view:
positive_diff = diff >= 0
You need to close each if statement with an endif
{% if var1 %}
{{ var1|safe }}
{% else %}
{% if var2 %}
{{ var2|safe }}
{% else %}
{% if var3 %}
{{ var3|safe }}
{% endif %}{% endif %}{% endif %}
The "smart if" tag was just added in the development version (that will eventually become 1.2).
If you're using a stable release (1.1.x or earlier) you won't be able to use those comparison operators in the "if" template tag.
Edit: look just above the == operator