Modifying template according to date with django - python

I'm wanting to modify the options on a template according to the date.
The code I'm suspecting will look something like this:
{% for campaign in filter.qs %}
{% if campaign.event_date__gte=datetime.today() %}
<code>
{% endif %} {% endfor %}
I believe my issue is that I'm trying to write it like a view - I'm just not too sure how to edit this within the template and not the views.py

You can do so with a property method by adding it to your model class.
import datetime
today = datetime.datetime.today()
class ModelClass(models.Model):
# fields
#property
def is_future_date(self):
return self.event_date >= today
{% for campaign in filter.qs %}
{% if campaign.is_future_date %}
# <code>
{% endif %}
{% endfor %}
But in case you have multiple different dates that require comparison, or you want to know whether it's a past, present future date, writing a property method for each model is NOT THE BEST ONE. So instead of property method, I would suggest writing a tag filter, then import it to your template, so you will be able to compare dates wherever in your template for whatever instance.
Here an example:
from django import template
register = template.Library()
import datetime
#register.filter
def is_future_date(date):
return date >= datetime.datetime.today()
To use it in your template, call it that way
{% for campaign in filter.qs %}
{% if campaign.event_date|is_future_date %}
<code>
{% endif %}
{% endfor %}
Another date in your template:
{% if another_instance.date|is_future_date %}
# I am able to do it with whatever model
# no need to create multiple property methods
{% endif %}

i think sample solution for is to create model property
class YOUMODEL():
#property
def is_today_or_after(self):
return self.event_date > datetime.today()
and then use in the template:
{% for campaign in filter.qs %}
{% if campaign.is_today_or_after %}
<code>
{% endif %} {% endfor %}

Related

How to check existence of an object using pk in django template?

I tried this if condition to show previous and next posts only if it exists in database.
{% if blog.pk|add:-1 %}
Previous Post
{% endif %}
{% if blog.pk|add:1 %}
Next Post
{% endif %}
but, it kinda ignores the condition and always show next and previous posts buttons owing to the fact that this condition is wrong. How do I fix this?
Please, don't implement this in the template. Templates should be used for rendering logic, not business logic.
You can define a method for example on your Post object to obtain the previous and next item:
class Blog(models.Model):
# …
def get_next(self):
return Blog.objects.filter(pk__gt=self.pk).order_by('pk').first()
def get_previous(self):
return Blog.objects.filter(pk__lt=self.pk).order_by('-pk').first()
Then you thus can use these methods:
{% with prev_blog=blog.get_previous %}
{% if prev_blog %}
Previous Post
{% endif %}
{% endwith %}
{% with next_blog=blog.get_next %}
{% if next_blog %}
Next Post
{% endif %}
{% endwith %}
This will also fetch Blog objects if there is a "gap". So if there is no Blog object with pk=4, then the get_previous of a Blog with pk=5, will be a Blog with pk=3.

Django; How to do conditionals for custom templatetags

I've been working on Django project. Seems like conditionals doesn't work for templatetags. How can I make it work?
my custom templatetag is like this.
register = template.Library()
#register.simple_tag(takes_context=True)
def get_counts(context):
...
return counts
and in templates
{% load app_name_tags %}
...
{% if not get_counts == 0 %}
{% get_counts %}
{% endif %}
but this conditional doesn't work. How can I fix this?
Try this, maybe it will work:
{% get_counts as counts %}
{% if not counts == 0 %}
{{ counts }}
{% endif %}

Does not work cycle "for"

I have a models.py:
class Part(models.Model):
Party_number = models.CharField(max_length=10)
Film = models.CharField(max_length=5)
viesws.py:
from django.shortcuts import render
from django.views.generic import ListView
from description.models import Part
class PartyNumView(ListView):
template_name = 'part_list.html'
model = Part
def partList(self, request):
my_var = Part.objects.all()
return render(request, 'part_list.html', {"my_var": my_var})
And HTML template part_list.html:
{% extends 'base.html' %}
{% load staticfiles %}
{% load static %}
{% block activeButton %}
<li class="active">Описание партий</li>
<li>Ic и QE</li>
{% endblock %}
{% block tableName %}
Список партий
{% endblock %}
{% block content %}
{% for object in my_var %}
{{object.Party_number}}
{% endfor %}
{% endblock content%}
My question is why part of code which consist cycle "for" does not working? i.e. objects of Party_number does not displayed on html page
UPDATE
I change object.Party_number to {{object.Party_number}}, but whatever it does not working
You have defined a custom method, partList, but it is not being called from anywhere. The method is pointless and you should delete it.
If you want to add data to the template context in a class-based view, you need to define get_context_data. However there is no reason to do that here as it would just do what ListView does for you anyway. You should use the variable that the view automatically populates, which is object_list.
{% for object in object_list %}
{{ object.Party_number }}
{% endfor %}

If statment doesn't work in a template file

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 %}

Django Template - Stop processing template

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

Categories