Does Django DateTimeField supporting time with time zone information? - django

When I post a time with timezone information eg:2013-02-27T14:00:00-05:00 to a Django datetime field throws a form error "Enter a valid date/time.".
My form field is defined as below
time = forms.DateTimeField()
I also tried passing in date formats to the form filed. eg:
DATE_FORMATS = [
'%Y-%m-%dT%H:%M:%S-%z',
]
time = forms.DateTimeField(input_formats=DATE_FORMATS)
Does Django DateTimeField not support time with timezone information?

Yes! Django DateTimeField supports timezones, but if you take a look at the documentation, you have to specify it separately from the actual DateTime in your form. Specifically, the documentation recommends that you activate a timezone on a per user basis, otherwise you will always end up entering the DateTime in the default timezone.
https://docs.djangoproject.com/en/dev/topics/i18n/timezones/#time-zone-aware-input-in-forms
This is the documentation I used for my project, and it worked out well.
In addition, if you need to specify a specific timezone in a form field, you can always create a drop down field with all of the timezones in it, and then save the DateTime in your view with the correct timezone.

Related

How can I convert the DateTimeField in Django from UTC to enduser's timezone (usually PST) when querying a Django model?

I'm querying a Django model connected to a table in my Postgres database that contains a datetime stored in UTC.
My query code looks something like this:
query_set = table_object.objects.values()
One of the columns in the query set is the datetime value in UTC.
The model looks like this:
class ops_inbox_view(models.Model):
requested_date = models.DateTimeField()
other_item = models.CharField(max_length=20)
other_item2 = models.CharField(max_length=40)
other_item3 = models.CharField(primary_key=True, max_length=10)
other_item4 = models.CharField(max_length=50)
other_item5 = models.CharField(max_length=50)
other_item6 = models.CharField(max_length=50)
I want to convert this into PST or robustly in the enduser's local time zone. My current solution is to use pandas with dt.tz_localize and dt.tz_convert after loading the query set into a dataframe but I'm trying to find a solution that is easily manageable in one location of the project file structure of the app. In my settings.py, I have TIME_ZONE set to 'US/Pacific' but because I'm using Pandas, the conversion to PST is not automatically done and will have to change many lines of code in my views.py to make the conversion with pandas.
Is there a way to not use Pandas and instead either make the field timezone aware or make the explicit conversion in the query code? Also looking for any other best practices in timezone management and display. Serving this datetimefield into an html file...
You can use F() with annotate
from datetime import timedelta
from django.db.models import DateTimeField, ExpressionWrapper, F
table_object.objects.annotate(modified_date=ExpressionWrapper(F('requested_date')+timedelta(minutes=960), output_field=DateTimeField())).filter(modified_date='2019-11-30')
Here you need to +/- minutes to convert utc datetime to your(PST) timezone and it will store converted dates into modofied_date, after that we can filter it.
Note:
You don't need to use pandas to convert timezones. Django good built-in timezone management tools.
Their timezone docs are quite good as well, so I'd suggest reading it all the way through.
The problem you're havingĀ seems very similar to one described in their docs

saving date and time of user response in django model field

i am making this app in django where on a particular html template if the user selects a particular response by clicking on it, the date and time at which the user clicked that particular response is stored in my database.
part of models.py
class userresp(models.Model):
rid=models.Integerfield(unique=True,default=0)
uid=models.Foreignkey(user,to_field='uid',on_delete=models.CASCADE)
resp=models.ForeignKey(elementsound,to_field='csid',on_delete=models.CASCADE)
date=models.DateTimeField()
time=models.DateTimeField()
so how do i store that? and what will be the extra parameters in the DateTimeField of both?
You can do the what you require inside a View by overriding the post() method.
To store the user's response time, you can make use of django's builtin timezone module.
So you just need to do:
from django.utils import timezone
date_and_time = timezone.now()
timezone.now() returns the system date and time of the server.
And by the way, you don't need two 'DateTimeField's to store the date and time. One is enough, it can store both the date and time.
Otherwise you can just get the current date and time at the time of userresp object creation.
class userresp(models.Model):
rid=models.Integerfield(unique=True,default=0)
uid=models.Foreignkey(user,to_field='uid',on_delete=models.CASCADE)
resp=models.ForeignKey(elementsound,
to_field='csid',
on_delete=models.CASCADE)
date_and_time=models.DateTimeField(auto_now_add=True)

Django DateTimeField hide date

I have a model where an object is called time which is model.DateTimeField(default=datetime.now)
I also have a form where the user can specify the time, but I wanted to only have the H: M in there, not the whole datetime.
I tried using the TimeInput widget in my form, but that would give me an error upon submitting because I didn't have the 'date' portion of the DateTimeField. If I use models.TimeField for time, I lose the ability to keep track of the date in the admin page.
How can I hide the date from showing in my form?
Worked around the problem by having one model as DateTimeField and another as TimeField.

Retrieve timezone aware DateTimeField in Django

In my models, I have a DateTimeField say
class ReturnEvent(models.Model):
book_title = models.CharField()
return_time = models.DateTimeField()
When I retrieve the return_time to be printed, for example:
return_event = ReturnEvent.objects.get(id=1)
print(return_event.return_time.strftime("%H:%M"))
I am seeing the datetime unaware time like:
2016-06-18 08:18:00+00:00
However, I like to see the local time using strftime.
2016-06-18 10:18:00+02:00
Is there a quick solution for this?
If you have USE_TZ = True in your settings, Django stores all the datetime objects in the database as UTC and convert them to your TIME_ZONE=XYZ from settings.py on the fly when rendering in the templates.
That is why, when retrieved from the database, datetime object is timezone aware but it has UTC as its timezone (hence +00:00 in 2016-06-18 08:18:00+00:00). As, you are converting the time to str yourself (and not rendering in the template) so Django does not convert it to your TIME_ZONE setting. You need to convert it yourself to your desired TimeZone.
If you want to convert it to the TimeZone from your TIME_ZONE setting, you can do
from django.utils import timezone
to_tz = timezone.get_default_timezone()
print return_event.return_time.astimezone(to_tz).strftime("%H:%M")

Saving DateTimeField with mongoengine

Using the Django framework (1.3.1), together with Mongoengine.
When trying to save a posted field (the due date), it bails out with a
ValidationError (cannot parse date "2013-12-31": ['DueDate'])
However when saving the date via datetime.datetime.now() it works fine. After searching for examples, I'm out of options.
The related parts of my code (with a normal HTML form using the text input tag):
views.py
goal.DueDate = request.POST['duedate']
goal.save()
models.py
class Goal(Document):
DueDate = DateTimeField()
last_update = DateTimeField(required=True)
Any idea?
Update (can't answer myself yet):
Ok.. found the solution. Typing it, apparently gave new insights.
goal.DueDate = datetime.datetime.strptime(request.POST['duedate'],
'%Y-%m-%d')
DateTimeField expects a datetime, not a string.
If the format is well known, you can use strptime like in your update, or dateutil parse method which is able to guess format.
You should also think about adopting a safer ISO formatted string send in the form from the web side.