Creating a date filter in jinja2 - python

I'm trying to work out the age of a record in my jinja2 with a filter. I created a simple filter in the following way. The date is stored in a mongodb field and its original form should be of the format of the python datetime object. Here is an example of the record:
"date_update": {
"$date": "2016-02-29T11:13:41.730Z"
},
app.jinja_env.filters['record'] = lambda u: record(u)
def record(date_obj):
print(date_obj)
print(type(date_obj))
return (datetime.datetime.today() - date_obj).days
I use the filter in the following way:
{{ myrec.date_update|record }}
If I look at the output, I see the following:
class 'jinja2.runtime.Undefined'
So my question is, how best should I deal with the dates in jinja2 in the correct format.

This looks like an unknown variable name within your template. From all you've posted so far, it is not clear whether you pass a variable myrec to the template renderer in the first place. So for better help, please post a minimal, self-contained example that exhibits the error.

Related

Can I use a variable as index in for loop in python?

I have this for loop on my python template to fulfill an array of values:
labels: [{% for bftimes in dataBF.buffers.0.times %} "{{ bftimes }}", {% endfor %}]
I would like to know if I can use an int variable as an index instead writing it directly, as seen on the code above.
I need to use the index of the selected value of a dropdown:
//returns the index of the selected value
document.getElementById("buffer").selectedIndex
The question needs more context to help us understand your goal. It seems you are mixing python with javascript data structures.
My general recommendation is that you first prepare the python data structure to what you will need and then convert it to json. Looping within Django template language should be used only on simple cases.
If you use django>=2.1 you can use json-script template tag
{{ data|json_script:"my-data" }}
https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#json-script
If not, you can use
# views.py
import json
def foo(request):
dataBF = {"a": [{"c": [1,2,3,1,1]},{"d": [1,2,3,1,1]}]}
# here you can manipulate the data accordingly to what you need
data = json.dumps(dataBF)
return render(request, "index.html", context={"data": data})
On the template side
<script>
const datajs = {{ data | safe }};
</script>
The datajs is a javascript object that you can work with.
I've made an example that you can check https://repl.it/#IvanPereira/python-to-javascript-django-template
You can do this in 2 ways.
Store all values in a list, which JavaScript will consider as json array, and loop over using JavaScript itself. This way you won't be able to update records from server and all values that has to be looped over should be pre-fetched.
You can use AJAX call to pass the selected index from JavaScript and return the new array and update that in the template using JavaScript itself.

Permanently replace value in Django

After extensive googling, I still havent come up with an effecient way to solve this.
Im creating a website using Django. I have a db which contains time data, more specifically dates. The value for "the present" is set to 3000-01-01 (YYYY-MM-DD) as is common practice for time-querying.
What I want to do is display a string like "Now" or "Present" or any other value instead of the date 3000-01-01. Is there some sort of global override anywhere that I can use? Seems like a waste to hard-code it in every view/template.
Cheers!
Since this is rendering, I would advice against "subclassing" the DateField such that it renders 'now' instead of the original date(..) object: it will make calculations in the model layer more cumbersome.
Probably a good way to deal with this is implementing a template filter [Django-doc], for example we can construct a file:
# app/templatetags/nowdate.py
from django import template
register = template.Library()
PRESENT = date(3000, 1, 1)
#register.filter
def nowdate(value):
if value == PRESENT:
return 'present'
return value
The templatetags directory of the app application, needs to contain an __init__.py file as well (an empty file), and the app of course needs to be part of the INSTALLED_APPS in the settings.py.
Then we can use it in the template like:
<!-- app/templates/app/some_template.html -->
{{ some_model.some_date_field|nowdate }}
Here we thus fetch the some_date_field of the some_model variable (this attribute is thus a date(..) object), and we pass it through the nowdate filter we have constructed such that, if it is 3000-01-01, it is replaced by the 'present' string.
The advantage here is that if we later change our mind about what date the "present" is, we can easily change it in the template filter, furthermore we can easily extend it, for example by adding a 'past', 'future', etc.

django template filter for all variables of specific type

In Django, I want to use a specific filter in all of my templates for all variables of a specific type.
For example let's say I want to use a filter that will convert date to Jalali Calendar if necessary based on user settings. In this case I want this filter to be applied to all variables I'll use in my templates that are a date.
I have a template called base.html which all of my templates extends it.
How can this be accomplished?
UPDATE: I'll use an example to clarify what I want to do exactly.
I have a model called Post which has field called publish_date. sth. like this.
class Post(models.Model):
title = models.CharField()
content = models.TextField()
publish_date = models.DateTimeField(auto_now_add=True)
Now when I'm outputting a post using a template I want all of my posts publish_date and all of my other variables in the template which are representing a date to be filtered using a filter called jalali_date. which will format dates to sth I want.
I know how to use custom tags and filters but I don't know how to accomplish sth. like this using them(if it's possible to do this using them).
UPDATE 2:
Just to more clarify: I have already written jalali_date filter. the problem is how to apply it automatically to all variables in my template that are a date.
If you want to implement this by a custom filter read about filters here, also below code maybe can help you:
import datetime, time
from django import template
import khayyam
register = template.Library()
def jalali_date(date):
"""Converts Date into JalaliDate"""
timestamp = time.mktime(datetime.datetime.timetuple(date))
jalali_date = khayyam.JalaliDate.fromtimestamp(timestamp)
return str(jalali_date)
register.filter('jalali_date', jalali_date)
and then in template you can use it similar below(suppose templatetag file nam is jdate):
{% load jdate %}
...
{{ publish_date|jalali_date }}
...
but if you want to automatically recognize and change values of certain types you must use MiddleWares (not filters), read snippet code about a custom MiddleWare here.
Note: for using non-builtin filters, you must add container app in INSTALLED_APPS.

Finer control over Django timeuntil output possible?

I'm currently using the timeuntil tag to show an items expiration date. It's currently spitting out...
{{rental_till|timeuntill}}
Which produces...
3 months, 1 week
Is it possible to get it to just show, the months, for example? Or any type of finer control over the output format, similar to the date tags.
To only show months, you could write a simple template filter that splits the string on the comma, and returns the first item of the resulting list. The filter code would look like this:
from django.template import Library
register = Library()
#register.filter
def split_timeuntil(duration):
return duration.split(",")[0]
Then in your template: {{rental_till|timeuntil|split_timeuntil}}
However, the timeuntil filter does not have the kind of formatting date has. You can easily create a custom filter that returns the format you want by copying the timeutil code in django/template/defaultfilters.py and django/utils/timesince.py.
No, timeuntil doesn't have any options, but you can simply create your own templatetag based on timeuntil and make it do whatever you like. See: https://code.djangoproject.com/browser/django/tags/releases/1.3/django/template/defaultfilters.py (line 729)

django autoconverting datetime property

my datetime property is saving in mysql in this format 2011-03-17 00:00:00 but after fetchind the data with filter function it is giving March 17,2011 midnight but i have not say to do any this type of task. My question is how can i insist django to stic to show same value what is saved in MYSQL.
you'll want to use the datetime format, django's DateTimeField[1] really is a wrapper for datetime.datetime.
in the templates you can use the date[2] filter to apply the format you want for example:
{{ item.date|date:"Y-m-d H:i:s" }}
This should print out 2011-03-17 00:00:00 in the template. In views use datetimes.strftime[3]
[1] http://docs.djangoproject.com/en/dev/ref/models/fields/#datetimefield
[2] http://docs.djangoproject.com/en/1.2/ref/templates/builtins/#date
[3] http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior
I have a feeling your database schema knows this is a date, right? In that case it's not being stored in the format you describe, but as some representation such as seconds since the era.
This means that when you retreave it your code has to do something with it to make it look right. If you don't tell it how to look it'll default to the format you see, but if you use strftime in your python code and a filter in your templates you can make it look however you like, including the original format how you saw it.
Of course the easy way out is to store it in the db as text...

Categories

Resources