I have a model with two TimeFields. I want to show the time difference in a template (ie, 27 minutes). I see the filter timesince, but it isn't working; I think it only accepts datetimes but my models have stored times only.
Response to #HAL:
'datetime.time' object has no attribute 'year'
Exception Location: C:\Python27\lib\site-packages\django\utils\timesince.py in timesince, line 32
You can use timesince template tag.
You can only compare two time stamps if you know their corresponding dates and timezones.. The datetime.time class contains only the time. I strongly advise you to consider using a DateTimeField (which uses datetime.datetime) in this case.
If you are sure that both datetime.time objects are having the same date and timezone, then you can add method to your model like this:
import datetime
from django.utils.timesince import timesince
class MyModel(models.Model):
...
def get_time_diff(self):
dummydate = datetime.date(2000,1,1) # Needed to convert time to a datetime object
dt1 = datetime.combine(dummydate,self.t1)
dt2 = datetime.combine(dummydate,self.t2)
return timesince(dt1, dt2) # Assuming dt2 is the more recent time
Here the time values are upgraded to a datetime value using an arbitrary date. You can invoke this from the template as {{ obj.get_time_diff }}.
Related
Time format
"2018-12-13T05:20:06.427Z"
django providing time zone in above format when i am fetching data from database using ORM query.
In my model field is in below way.
models.DateTimeField(auto_now=True, blank=True,null=True)
How can i convert it into "24 feb 2018" like this
Apart from #Sosthenes Kwame Boame answer, you can use strftime for formatting.
import datetime
time = datetime.datetime.now().strftime('%d %b %Y')
Out[13]: '13 Dec 2018'
Instead of passing datetime module to time variable, you should pass your model field's value.
If you want to learn more about format type then you can visit the documentation page.
I am guessing you want to display this on the frontend?
You need to do this in your template:
{{ object_name.datefield_name|date:'j b Y' }}
So you call the datefield and render it with the '|date' tag with a format assigned ':'FORMAT''.
Learn more about the date tag, along with the various formats here: https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#date
I have a model with DateField:
end_date = models.DateField(default=datetime.date.today)
In the template I need to calculate how many days there is to the end_date from now.
I tried:
{% now "d m Y"|timeuntil:placement.end_date|date:"d m Y" %}
but it doesn't work. How can I get number of days until that date?
There is a limitation to using Django functionality in Templates. You could solve this by combining the timesince and timuntil methods to calculate the difference between two dates. However you would benefit more from doing this in a python view and then pass the result to the template.
This way you can truly use the power of Datetime. So in your views.py and the specific function that renders the template, include this:
d0 = datetime.now().date()
d1 = placement.end_date
delta = d0 - d1
print delta.days
You can read more about the Datetime documentation here. Now you can pass that variable along in a context, or by itself to be rendered by the template
Option 1: Create a custom filter
Create a custom filter function which grabs the current date and calculates the days.
In your template you simply use:
{{ placement.end_date | days_until }}
To define and register the filter, include this code in a python file:
from datetime import datetime
from django import template
register = template.Library()
#register.filter
def days_until(date):
delta = datetime.date(date) - datetime.now().date()
return delta.days
More about Django custom template tags and filters here.
Option 2: Calculate the days in your view and store it in the context
This is straightforward for one date. You calculate the days and store the information in the context:
from datetime import datetime
delta = placement.end_date - datetime.now().date()
context['days_left'] = delta.days
In your template you access it directly:
{{ days_left }}
But, if you want to pass a list of "placements" to the template, you will have to "attach" this new information to every placement. This is a different topic and the implementation depends on the project... you can create a wrapper over placement... or store the days_left in a different dictionary...
Because I like Django built-in filters
timesince
Formats a date as the time since that date (e.g., “4 days, 6 hours”).
Takes an optional argument that is a variable containing the date to
use as the comparison point (without the argument, the comparison
point is now). For example, if blog_date is a date instance
representing midnight on 1 June 2006, and comment_date is a date
instance for 08:00 on 1 June 2006, then the following would return “8
hours”:
{{ blog_date|timesince:comment_date }}
Comparing offset-naive and offset-aware datetimes will return an empty
string.
Minutes is the smallest unit used, and “0 minutes” will be returned
for any date that is in the future relative to the comparison point.
I have a field which will represent the start time of an event and I am using the Django DateTimeField for this.
This field is mandatory but sometimes the users will only know the start date and not the time.
Is there anyway to make the time part optional and keep the date part mandatory?
Maybe you should try to separate date from time. There are DateField and TimeField for that.
Example for use at the views or models:
You can use function strptime to show the datetime field any formats.
from datetime import datetime
datetime.now().strftime('%Y-%m-%d')
# print string '2013-06-25'
Example for use at the templates:
you can use templatetag date
{{ datetime_field|date:"Y-m-d" }}
I am working on a django- Google app engine project. A user inserts some value and the datetime field is auto filled using google app engine DateTimeProperty(auto_now_add=True) property. Now, I have to display on the template the difference of this time and the current time when the user is viewing the result.
For e.g. if the inserted time was 5:00 and the user is viewing the post at 6:00, the result should be 1 hour. Is there any builtin filter available with the Django templates to perform the same? I tried timesince as:
{{ topic.creation_date| timesince: now }}
where creation_date is a datetime field. But its not working.
Please suggest.
Thanks in advance.
Do you have a variable called "now" in your context? If not, that will fail.
However, you don't actually need one, because if you call the timesince filter without an argument, it will use the current time. So just do:
{{ topic.creation_date|timesince }}
why don't you use time.time()? And for creation date you first have to insert given row into database. That means you can read it.
from datetime import timedelta
yourmodel.save()
cdate= yourmodel.creation_date
seconds = time.time() - time.mktime(cdate.timetuple())
timediff = str(timedelta(seconds=seconds))
I am storing dates as an integer field in the format YYYYMMDD, where month or day is optional.
I have the following function for formatting the number:
def flexibledateformat(value):
import datetime, re
try:
value = str(int(value))
except:
return None
match = re.match(r'(\d{4})(\d\d)(\d\d)$',str(value))
if match:
year_val, month_val, day_val = [int(v) for v in match.groups()]
if day_val:
return datetime.datetime.strftime(datetime.date(year_val,month_val,day_val),'%b %e, %Y')
elif month_val:
return datetime.datetime.strftime(datetime.date(year_val,month_val,1),'%B %Y')
else:
return str(year_val)
Which results in the following outputs:
>>> flexibledateformat(20100415)
'Apr 15, 2010'
>>> flexibledateformat(20100400)
'April 2010'
>>> flexibledateformat(20100000)
'2010'
So I'm wondering if there's a function I can add under the model field class that would automatically call flexibledateformat.
So if there's a record
r = DataRecord(name='foo',date=20100400)
when processed in the form the value would be 20100400 but when output in a template using {{ r.date }} it shows up as "April 2010".
Further clarification
I do normally use datetime for storing date/time values. In this specific case, I need to record non-specific dates: "x happened in 2009", "y happened sometime in June 1996".
The easiest way to do this while still preserving most of the functionality of a date field, including sorting and filtering, is by using an integer in the format of yyyymmdd. That is why I am using an IntegerField instead of a DateTimeField.
This is what I would like to happen:
I store what I call a "Flexible
Date" in a FlexibleDateField as an
integer with the format yyyymmdd.
I render a form that includes a
FlexibleDateField, and the value
remains an integer so that functions
necessary for validating it and
rendering it in widgets work
correctly.
I call it in a template,
as in {{ object.flexibledate }} and
it is formatted according to the
flexibledateformat rules: 20100416
-> April 16, 2010; 20100400 -> April 2010; 20100000 -> 2010. This
also applies when I'm not calling it
directly, such as when it's used as
a header in admin
(http://example.org/admin/app_name/model_name/).
I'm not aware if these specific things are possible.
Also
I have already written a template filter that can perform this function --
({{object.flexibledate|flexibledateformat}}) --
but I'd rather not have to call the filter every time I want to output one of these values. Except when outputting the form, I pretty much never want to see the number.
I think the most djangoish way of accomplishing a similar effect would be to define a custom method on a model:
class Model(models.Model):
date = models.IntegerField()
...
def flexibledate(self):
return flexibledateformat(self.date)
You can use it in a template like this:
{{ r.flexibledate }}
I also wonder why are you using an IntegerField instead of a native DateTimeField.
Update: You can still use the custom method as an option for list_display in Django Admin. If you want the column header to say something else then simply the method's name use the "short_description" option, like this:
class Model(models.Model):
date = models.IntegerField()
...
def flexibledate(self):
return flexibledateformat(self.date)
flexibledate.short_description = 'Date'
and then you just use it the same way you would use an ordinary field:
class YourModelAdmin(admin.ModelAdmin):
list_display = ('title', 'flexibledate')
admin.site.register(YourModel, YourModelAdmin)
That is not necesary, read about humanize and filtertag time