I have a weird situation with if statement in Django. It seems that django doesn't see it and I don't know why
my template file:
<div class="article-intro">
<p>{{ article.jezyk }} </p>
{% if article.jezyk = 'EN' %}
{% for sala in sala %}
<div>{{ sala }}</div>
{%endfor %}
{% endif %}
</div>
It looks like this:
As we see on the picture tag:
{{ article.jezyk }}
returns a value 'EN'
Why then "if statment" doesn't work? Is there any explanation?
My views.py
from django.shortcuts import render_to_response
from articles.models import Article
from sale.models import Sala
from godzina.models import Godzina
from jezyk.models import Jezyk
def articles(request):
return render_to_response('articles.html',{'articles' : Article.objects.all(),'godzina': Godzina.objects.all(),'sala': Sala.objects.order_by('jezyk') })
Once again you have not provided the information necessary to answer your question, ie the models. However we know from your previous questions that Article.jezyk is a ForeignKey. When you output a FK field in the template, it will print the result of the unicode method, but that doesn't mean they are actually equal. You need to compare the field itself, for example:
{% if article.jezyk.language = 'EN' %}
or whatever the field is on the Jezyk model that contains the language code.
try this ifequal :
e.g
{% ifequal article.jezyk 'EN' %}
<!-- Ur code -->
{% endifequal %}
use == operator
e.g.
{% if somevar == "x" %}
This appears if variable somevar equals the string "x"
{% endif %}
Documentation: link
Use other variable name in for loop. Same sala variable is used for iterator.
e.g.:
{% for i in sala %}
<div>{{ i }}</div>
{% endfor %}
Related
I have a django app with a basic model (Job). Now in my template I would like to check if an instance exists of that model or not. I want to project a text if there is nothing yet to show, otherwise I'd like to show the model attributes.
Somehow like so (which obviously doesn't work):
{% if job.title != "" %}
{{ job.title }}
{% else %}
hola
{% endif %}
Also tried:
{% for job in jobs %}
{% if job.title %}
{{ job.title }}
{% else %}
Hola
{% endif %}
{% endfor %}
It makes sense it doesn't work because how can I loop through it or return something if it doesn't exist. Is there a simple way to even do that in a template? Or do I have to write my own function? Or what would be a way to do that?
Help is of course very much appreciated
You can use the {% if %} tag. As Django doc says:
The {% if %} tag evaluates a variable, and if that variable is “true” (i.e. exists, is not empty, and is not a false boolean value) the contents of the block are output.
So you can do something like this:
{% if job %}
{{ job.title }}
{% else %}
<p>Hi from Uruguay</p>
{% endif %}
If you need this inside a for, as #dirkgroten said, you need to use the {% empty %} tag. There is an example in the Django doc.
views.py:
def get(request):
p = Publisher.objects.filter(name='tux')
return render(request, 'main.html', {'items': p[0]})
main.html:
<html>
<body>
{{ items }}
<hr>
{% if 'tux' in items %}
<h1>this is tux</h1>
{% else %}
<h1>sorry!</h1>
{% endif %}
</body>
</html>
What is printed on the webpage:
tux
sorry!
And what about if I want to use {% ifequal %} tag?
What syntax should be used? I tried this:
{% ifequal {{items}} 'tux' %}
and it turned parse error, and I also tried this:
{% ifequal items 'tux' %}
but the result was again:
tux
sorry!
You cannot use it like this: {% if 'tux' in items %}, since items is an object.
Use {% if 'tux' in items.name %} instead.
The reason you get 'tux' displayed in the case of {{items}} is that your model returns name field as a unicode representation.
I wrote a custom tag named addattrs that allow me add HTML attributes easily.
I uses it that way:
<div>
<label>Last name</label>
{{ form.last_name|addattrs:"class=blue-form&placeholder=Please enter your name" }}
</div>
It works well. But now, I'd like to add the value attribute to HTML:
<div>
<label>Last name</label>
<!-- last_name is availaible from the current context -->
{{ form.last_name|addattrs:"class=blue-form&value=last_name" }}
</div>
The problem is last_nameis not evaluated and wrote as is in my form. How to force last_name to be evaluated? I tried a {% with last_name as myvariable %} block, but the result is exactly the same.
Thanks.
EDIT
The alecxe solution works.
However, if the value is a datetime, it does not work anymore (no python Error but no attribute at all in the HTML.) I tried this:
{% with "class=blue-form&value="|add:birth_date as attrs %}
{{ form.birth_date|addattrs:attrs }}
{% endwith %}
You can use add template filter:
{% with "class=blue-form&value="|add:last_name as attrs %}
{{ form.last_name|addattrs:attrs }}
{% endwith %}
For the date value, you need to convert it to a string first. Either in the view, or in the template via date template filter, example:
{% with birth_date|date:"D d M Y" as my_date %}
{% with "class=blue-form&value="|add:my_date as attrs %}
{{ form.last_name|addattrs:attrs }}
{% endwith %}
{% endwith %}
I use:
DjangoCMS 2.4
Django 1.5.1
Python 2.7.3
I would like to check if my placeholder is empty.
<div>
{% placeholder "my_placeholder" or %}
{% endplaceholder %}
</div>
I don't want the html between the placeholder to be created if the placeholder is empty.
{% if placeholder "my_placeholder" %}
<div>
{% placeholder "my_placeholder" or %}
{% endplaceholder %}
</div>
{% endif %}
There is no built-in way to do this at the moment in django-cms, so you have to write a custom template tag. There are some old discussions about this on the django-cms Google Group:
https://groups.google.com/forum/#!topic/django-cms/WDUjIpSc23c/discussion
https://groups.google.com/forum/#!msg/django-cms/iAuZmft5JNw/yPl8NwOtQW4J
https://groups.google.com/forum/?fromgroups=#!topic/django-cms/QeTlmxQnn3E
https://groups.google.com/forum/#!topic/django-cms/2mWvEpTH0ns/discussion
Based on the code in the first discussion, I've put together the following Gist:
https://gist.github.com/timmyomahony/5796677
I use it like so:
{% load extra_cms_tags %}
{% get_placeholder "My Placeholder" as my_placeholder %}
{% if my_placeholder %}
<div>
{{ my_placeholder }}
</div>
{% endif %}
If you want additional content to be displayed in case the placeholder is empty, use the or argument and an additional {% endplaceholder %} closing tag. Everything between {% placeholder "..." or %} and {% endplaceholder %} is rendered in the event that the placeholder has no plugins or the plugins do not generate any output.
Example:
{% placeholder "content" or %}
There is no content.
{% endplaceholder %}
Here's a very compact solution.
Template filter:
#register.filter('placeholder_is_empty')
def placeholder_is_empty(request, slot):
page = request.current_page
placeholder = page.placeholders.get(slot=slot)
return placeholder.cmsplugin_set.exists()
Usage in template:
{% if request|placeholder_is_empty:'myplaceholder' %}
<h1>Here comes some content... </h1>
{% endif %}
Depending on what you are trying to achieve, you can simply use CSS to hide the element if doesn't have content using the :empty selector. And if you are worried about white spaces you can use Django's in-build {% spaceless %} template tag to remove them.
So you'd get this template:
{% spaceless %}
<div class="hide_if_empty">
{% placeholder "my_placeholder" %}
</div>
{% endspaceless %}
And this CSS:
hide_if_empty:empty {
display: none;
}
Not exactly what was asked for as it doesn't remove the HTML - but this will solve the most common case where one wants to check if a place holder is empty, and doesn't require the introduction of a new template tag.
Based on the great answer form #Philip Zedler, a solution that works for both placeholder on django-cms pages, but also on placeholders "outside of the cms".
#register.filter()
def placeholder_empty(page_placeholder, slot=None):
"""
for page/slot, pass a page object, and a slot name:
{% if request.current_page|djangocms_misc_placeholder_empty:"content" %}
for a outside page placeholder, just the placeholder object:
{% if object.placeholderfield|djangocms_misc_placeholder_empty %}
also, with:
{% with ph_empty=object.placeholderfield|djangocms_misc_placeholder_empty %}
"""
placeholder = None
if isinstance(page_placeholder, Placeholder):
placeholder = page_placeholder
elif isinstance(page_placeholder, Page):
page = page_placeholder
try:
placeholder = page.placeholders.get(slot=slot)
except Placeholder.DoesNotExist:
pass
if placeholder:
# // return not placeholder.cmsplugin_set.filter(language=get_language()).exists()
return not placeholder.cmsplugin_set.exists()
return False
usage in template
{% if request.current_page|placeholder_empty:'content' %}
<h1>Fallback!</h1>
{% endif %}
It's in my djangocms-misc package
I took the extra compact solution here and created a templatetag that checks if a static placeholder is not empty:
from cms.toolbar.utils import get_toolbar_from_request
#register.filter("static_placeholder_is_not_empty")
def static_placeholder_is_not_empty(request, slot):
placeholder = StaticPlaceholder.objects.get(code=slot)
if get_toolbar_from_request(request).edit_mode_active:
placeholder = placeholder.draft
else:
placeholder = placeholder.public
is_not_empty = len(placeholder.get_plugins(request.LANGUAGE_CODE)) > 0
return is_not_empty
It's used like this:
{% load my_new_shiny_templatetag %}
{% if request|static_placeholder_is_not_empty:'my_static_placeholder' %}
<div class="something">
{% endif %}
{% static_placeholder "my_static_placeholder" %}
{% if request|static_placeholder_is_not_empty:'my_static_placeholder' %}
</div>
{% endif %}
I am looking for way to clean up a template in django. A simple solution would be to break this up into multiple templates, but we do not want to do that.
We basically have the following
{%if data.some_state %}
Display some markup
{% else %}
{%if data.some_state_2 %}
State 2 different html view
{% else %}
{%if data.process_data %}
Display some list of data
{% else %}
No Data to display!
{% endif %} <!-- if data.process_data-->
{% endif %} <!-- if data.some_state_2 -->
{% endif %} <!-- if data.some_state -->
So that is extremely confusing and hard to read. If I could do this in a "function" i would use if/else if or returns.
Is there a way in template language to do something like (stop_processing_template would tell the template we are done... ):
{%if data.some_state %}
Display some markup
{% endif %}
{% django_stop_processing_template %}
{%if data.some_state_2 %}
State 2 different view
{% endif %}
{% django_stop_processing_template %}
{%if data.process_data %}
Display some list of data
{% endif %}
{% django_stop_processing_template %}
No data provided !
I am not sure what your stop processing template logic would do; but a cleaner way to do your logic would be to write a custom tag that takes your arguments and then returns only the HTML relevant to your variables. This way you remove the if/else loops and instead replace all that with a simple {% do_stuff %} tag.
Edit
This is a very simple implementation to give you some idea on how the logic would go.
First, you create templates for each variation and store them somewhere django can find them.
Then, a simple tag that renders the exact template you want (this is non tested, psuedo):
from django import template
from django.db.models import get_model
register = template.Library()
class ProcessData(template.Node):
def __init__(self, var_name):
self.obj = get_model(*var_name.split('.'))
def render(self, context):
if self.obj.some_state:
t = template.loader.get_template('some_markup_template.html')
result = 'something'
else:
if self.obj.some_state_2:
t = template.loader.get_template('some_different_html_view.html')
result = 'something'
else:
if self.obj.process_data:
t = template.loader.get_template('some_list_data.html')
result = 'something'
else:
t = template.loader.get_template('no_data.html')
result = 'something'
return t.render(Context({'result': result}, autoescape=context.autoescape))
#register.tag
def process_data(parser, token):
try:
tag_name, arg = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError("%r tag requires arguments" % token.contents.split()[0])
return ProcessData(arg)
Finally, in your template:
{% load my_tags %}
{% process_data data.mymodel %}
You could use jinaj2 for templating that view (or the whole project), it supports if/elif/else branching:
{% if data.some_state %}
Display some markup
{% elif data.some_state_2 %}
State 2 different view
{% elif data.process_data %}
Display some list of data
{% endif %}
There are a couple different packages which it easy use jinja2 in a django project, I've used both coffin and djinja for this.
Though I think #burhan's approach is better, you could also do what you want to do by using a custom tag that sets a context variable to a boolean and than outermost else part could also be converted into a if tag
#Set a context variable nodata to True
{% setnodata True %}
{%if data.some_state %}
Display some markup
#Set context variable nodata to False
{% setnodata False %}
{% endif %}
{%if data.some_state_2 %}
State 2 different view
#Set context variable nodata to False
{% setnodata False %}
{% endif %}
{%if data.process_data %}
Display some list of data
#Set context variable nodata to False
{% setnodata False %}
{% endif %}
{% if nodata %}
No data provided !
{ % endif %}
The setnodata custom tag simply sets the context variable nodata to True or False depending upon the argument.
today I meet the same question.
And I find this tag {% verbatim %} {% endverbatim %} .This works in Django1.5+
An example:
{% verbatim %}
<div class="entry">
<h1>{{ title }}</h1>
<div class="body">
{{ body }}
</div>
</div>
{% endverbatim %}
You can also look below for more details:
https://groups.google.com/forum/#!topic/django-users/-_wBLDuzaNs
Handlebars.js in Django templates