I'm currently using django-tables2 to display a queryset of my model. One of the attributes of this model is a DateTimeField accurate to the millisecond which is being truncated to the minute in my table.
I had previously manually implemented a simple table in HTML and had no issues. My DateTimeFields were following true to the DATETIME_FORMAT applied in my settings:
settings.py
DATETIME_FORMAT = 'Y N j, H:i:s.u'
The problem has arisen since I began using django-tables2. Is there some way to modify the way it displays DateTimeFields or make it follow my specified DATETIME_FORMAT? I need to retain the sorting functionality so converting to a string is not an option.
I'm using render_table to display my table. The following is my table class:
class ModelTable(tables.Table):
class Meta:
model = Measurement
sequence = ('date_time', 'latitude', 'longitude',
'depth', 'soundvel', 'instrument')
Problem solved.
django-table2's DateTimeColumn class seems to be looking for a SHORT_DATETIME_FORMAT rather than the DATETIME_FORMAT in my settings.py. Updated the value in my settings file and everything is in working order.
This confused me for a while as I tried to use the Python datetime formatting options. The formatting options for Django templates apply in django-tables2, and are fully enumerated at the Django docs:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#std:templatefilter-date
From that, if you have a model with one datetime column, and you want their birthday to be formatted as Month Day Year, Hour:Minute AM/PM, then you would enter the following:
class MyTable(tables.Table):
birthday = tables.DateTimeColumn(format ='M d Y, h:i A')
class Meta:
model = Person
attrs = {'class': 'table'}
fields = ['birthday']
You can add 'format' as argument to DateTimeColumn.
https://django-tables2.readthedocs.io/en/latest/_modules/django_tables2/columns/datetimecolumn.html
class DateTimeColumn(TemplateColumn):
"""
A column that renders `datetime` instances in the local timezone.
Arguments:
format (str): format string for datetime (optional).
Note that *format* uses Django's `date` template tag syntax.
short (bool): if `format` is not specified, use Django's
``SHORT_DATETIME_FORMAT``, else ``DATETIME_FORMAT``
Related
When saving timestamp in Django's DateTimeField using auto_now_add this way:
creation_timestamp = models.DateTimeField(auto_now_add=True)
the field is saved with miliseconds:
2018-11-20T15:58:44.767594-06:00
I want to format this to be displayed without miliseconds:
2018-11-20T15:58:44-06:00
But the only option I could come up with does not exactly show what I need:
format="%Y.%m.%dT%H:%M:%S%z" gives me 2018.11.20T15:58:44-0600
How do I format this field the way I need?
Alternatively I'd rather save DateTimeField without milliseconds at all but does auto_now_add allow to do this sort of thing?
If you want to format it on when displaying it, you can use: creation_timestamp.strftime("%Y-%m-%d%H:%M:%S")
You can also make DateTimeField to save it in that format, but this would request a set of changes which will apply system wide:
In your settings file set the follwing:
DATETIME_FORMAT="%Y-%m-%d%H:%M:%S"
L10N=False to make sore localization data doesn't take precedent when it comes to dates format.
USE_TZ=False
But, consider the fact that this changes will apply by default to all date time objects from your project.
You can override DateTimeField's value_to_string method and add the changes there. For example:
class CustomDateTimeField(models.DateTimeField):
def value_to_string(self, obj):
val = self.value_from_object(obj)
if val:
val.replace(microsecond=0)
return val.isoformat()
return ''
And use it in model:
created = CustomDateTimeField(auto_now_add=True)
I think you will have to use isoformat. Look at that answer:
Show the : character in the timezone offset using datetime.strftime
I use pandas to_datetime() function to convert the time to string format.
import pandas as pd
record_list = myModel.objects.all()
for idx, record in enumerate(record_list ):
st = str(pd.to_datetime(record.start_time))
record_list[idx].start_time = st
In Django I have a 1 input form that is created like this:
class ListTripsForm(forms.Form):
date_to_edit = forms.DateField(input_formats=['%m/%d/%Y'],
widget=forms.TextInput(attrs={
'class': 'form-control',
'id': 'trips_month'}),
initial=date.strftime(date.today(),
'%m/%d/%Y'))
The user selects a date (eg. 5/26/2017).
In the DB I have a datetime column.
Trying to get all the 'trips' from that day.
I've tried a few different ways and none have lead to success.
I am trying to add a filter to select just results from that day:
date = request.POST.get('date_to_edit', '') # users submitted date mm/dd/yyyy
user_trips_for_date = Trip.objects.filter(user_id=user.id, trip_date=datetime.date(date))
What's the best way to accomplish this?
First off, you'll have an easier time of things if you instantiate your form as normal and access the field rather than extracting it directly from request.POST. Part of the point of the form classes is to handle type conversions.
Once you have that, if trip_date is a DateTimeField:
form = ListTripsForm(request.POST)
user_trips_for_date = Trip.objects.filter(user_id=user.id, trip_date__date=form.cleaned_data['date_to_edit'])
Plus the usual validation code of course, the point is to a) use the form to get a datetime.date instance and then b) use a __date filter clause.
Date is in string format in database
class A(models.Model):
date = models.CharField(max_length=50, blank=True, null=True)
Yah i know it should be date type.
but now we have many records and we will soon change it to date type.
For current status i want get the objects greater than particular date.
So how can i use date__gte
example
objs = A.objects.filter(date__gte=datetime.now())
Is there any way to achieve this without converting date to datetime field.
I am not sure if that works. What you can try is a custom manager. So you can create a manager for your model, add something like date_gte and then convert the string to a datetime. Then you can user those operators as usual. That's a quick fix for now, but the best solution is to use a DateTimeField, which you want to do as far as I understood.
Example Manager:
from django.db import models
class MyManager(models.Manager):
def date_gte(self, date=datetime.now()):
items = []
for obj in self.all():
if datetime(obj.date) < date:
items.append(obj)
return items
Then you could call it like MyModel.objects.date_gte(date=datetime.now()).
Note: This is an expensive query and you may need to convert the simple list into QuerySet object. I haven't tested it, so this example should only help you get started.
There is no way to do this without a conversion (either in Django or the database during the query) to a proper DateTime type. You're trying to compare a datetime.datetime to a str. That won't work in normal Python and it won't work here.
What kind of string? if it is formatted to %Y%m%d, you can use .extra() method to do the query.
A.objects.extra(where=['date >= date_of_today'])
I've Django model which has foreign keys associated with other models. Each model is having same field names(attributes) created_at and updated_at
In every django queryset results I'll be getting datetime values.
Model.objects.all().values('created_at')
But I want to format the datetime field to "DD-MM-YYYY HH:MM:SS" and trim down the milliseconds in the django query results.
If I use "extra" and and date_trunc_sql like the following command
dt = connection.ops.date_trunc_sql('day','created_date')
objects.extra({'date':dt}).values('date')
Which works fine. But If I query like the following, its raising ambiguous statement error.
objects.extra({'date':dt}).values('date', 'x', 'y', 'z')
How to overcome this problem?
Solved it via #Yannics answer at: https://stackoverflow.com/a/60924664/5804947
This also avoids using extra which should be "a last resort" due to Django docs.
from django.db.models import F, Func, Value, CharField
qs.annotate(
formatted_date=Func(
F('created_at'),
Value('DD-MM-YYYY HH:MM:SS'),
function='to_char',
output_field=CharField()
)
)
Got the solution.
data = list(Model.objects.extra(select={'date':"to_char(<DATABASENAME>_<TableName>.created_at, 'YYYY-MM-DD hh:mi AM')"}).values_list('date', flat='true')
It's not just tablename.attribute, it should be dbname_tablename.attribute when we have multiple databases(ambiguous)
which will result list of created_at datetime values trimmed to 'YYYY-MM-DD HH:MM' format.
I don't think values() function would anything related to formatting datetime result. But why does that bother you? Can't you convert them to proper format when you try to display them? If you try to render them in the template, django has template filter date for formatting your datetime value: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#date
I'm having a bit of trouble with django's DateField model field. Shouldn't it be able to accept fiveDaysLater as a valid date object? When I try to add fiveDaysLater into the database, I get an error saying cannot add null value to date. However, the second I change the date field to a regular CharField, the fiveDaysLater value is added to the database with no problem. fyi if I print fiveDaysLater, I get 2011-09-28
My view:
def myView():
now = datetime.date.today()
fiveDaysLater = now + datetime.timedelta(days=5)
newDate = Speech(date = fiveDaysLater)
newDate.save()
My model
class Speech(models.Model):
date = models.DateField()
"However, the second I change the date field to a regular CharField..." Just a suspicion but if you made this change in your code, make sure to delete and recreated the Speech table using syncdb, otherwise, sqlite will not be aware of this change. (or you could change the datatype using sqlite exporer for firefox or something like that...)