Django - Date and Time Field Explanation - django

I have few questions regarding the Date and time fields both in the model and in the form class.
1.)In the docs for the date field what does the line "Normalizes to: A Python datetime.date object." mean? Does it mean that the field data stored in the request.POST dictionary on the submission of the form is a datetime.date object?If yes, then when does it do it when the form is submitted or do we have to call one of its functions?
2.)If i have a models.DateField() then while assigning data to it manually in a view should i assign a datetime.date object or a unicode object with the 'yyyy-mm-dd' format?
3.)If i take a date in my forms.DateField() in the '%d/%m/%y' format how do i assign it to my models.DateField() because that seems to accept only the 'YYYY-mm-dd' format?
If somebody could also suggest some links which explain these fields in detail with examples apart from the docs it would be helpful.

For first question, datefield saves date object and if you are saving any data( for example a string: "01-01-2015") to datefield, then you have to convert that data into date object. You will not get a date object in request.POST, if you use a form, then you can get it by using cleaned_data.(example below) From request.POST ,you will get an unicode object.( then you will need to convert it to date object, example below)
For second question, obviously you have to save dateobject, not unicode object.
For third question, in forms, To display initial field value properly formatted, use DateInput widget. To customize validation, use input_formats keyword argument of DateField. Here, from forms, you will get a date object in views, so it can be saved directly, like:
In model.py:
class DateModelClass(models.Model):
date= models.DateField()
In forms.py:
date= forms.DateField(widget=forms.DateInput(format = '%d/%m/%Y'), input_formats=('%d/%m/%Y',))
In views.py:
date_data= DateModelClass(date= form.cleaned_data['date'])
date_data.save()
Also you can convert a string of your desired format to Date Object like this:
>>import datetime
>>datetime.datetime.strptime(u"09/07/2014", '%d/%m/%Y').date()

Related

TimeField returning None in Django

I have an existing database I need to pull data from the timestamp field in Django. I created the Django model as a TimeField, but when I query the data I get 'None' instead of the data in the timestamp field.
From my model class: (there is more in the model, I just condensed this for readability)
class Report(models.Model):
upload_time = models.TimeField()
date = models.CharField(max_length=9)
#staticmethod
def get_reports(**query):
reports = Report.objects.order_by('date').filter(query)
for report in reports:
print(report.upload_time)
In my views.py I have a method that checks for the date I am looking for to pull all reports from that date. The database saved the date as a string, so I get that ok, then just turn it into a datetime object and call my get_reports method by passing the date into it. It works to get everything from the report except the timestamp.
What am I missing?

TypeError: unsupported operand type(s) for -: 'DateTimeField' and 'DateTimeField'

I have the following equation in a Django 2.1 class:
import datetime
class FormBacktest(forms.Form):
dateStart= forms.DateTimeField(label="Date Start", widget=DateTimePickerInput()
dateEnd= forms.DateTimeField(label="Date End", widget=DateTimePickerInput()
timeInMin = int((dateEnd-dateStart).total_seconds()/60)
I know from the documentation that the DateTimeField is a datetime.datetime instance, so this question should be overcomed.
Any recommendations?
Well, DateTimeField is a form field, not a datetime instance. However when you take input from that field, you will get a datetime object. you can access its value from cleaned_data, for example like this:
# in view
def someview(request):
form = FormBacktest(request.POST or None)
if request.method == "POST": # its a post request
if form.is_valid():
date_start = form.cleaned_data.get('dateStart')
date_end = form.cleaned_data.get('dateEnd')
difference= date_end - date_start # time delta object
Please check the documentation on more details on how to get data from form. Also, please remove timeInMin from form.
I'm a bit confused about what you're trying to accomplish but I'll try to help.It seems like you're mixing up forms and model instances.
If you want to show timeInMin on the form then you'll need to make it an Integer field (probably small will do) and then use javascript to do the math and update the field when a user enters the start and end date.
IF you want to set timeInMin on submit in the database for the model instance, and you don't care about updating the value with Javascript on the form when it's updated, then you'll just do it in your form handler view, or even by overriding the model's save method.
With what you have now, the DateEnd isn't instantiated when you're trying to reference it, and DateEnd isn't a value anyway, it's a form field.

Django: date field saved to model but not retrieved

Django 1.9 / Python 2.7
Given this model:
class CoursePurchase(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
course = models.ForeignKey(Course)
date_purchased = models.DateField(default=date.today())
I would expect date_purchased to store the date I enter into Django admin, and it does, according to my database browser:
However, retrieving the object in the view has today's date instead of the stored date:
(Note the date_purchased field of __unicode__ returns today's date instead of the stored date.
Here is the code I'm using to retrieve the instance:
cp = CoursePurchase(course=page.course, user=request.user)
where course and user return the expected values.
What am I missing? This seems fairly straightforward, but I can't get past this.
To set the current date on save, django provides special arguments to the DateField type:
Django documentation:
class DateField(auto_now=False, auto_now_add=False, **options)
A date, represented in Python by a datetime.date instance. Has a few extra, optional arguments:
DateField.auto_now
Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps. Note that the current date is always used; it’s not just a default value that you can override.
The field is only automatically updated when calling Model.save(). The field isn’t updated when making updates to other fields in other ways such as QuerySet.update(), though you can specify a custom value for the field in an update like that.
DateField.auto_now_add
Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it’s not just a default value that you can override. So even if you set a value for this field when creating the object, it will be ignored. If you want to be able to modify this field, set the following instead of auto_now_add=True:
For DateField: default=date.today - from datetime.date.today()
For DateTimeField: default=timezone.now - from django.utils.timezone.now()
The default form widget for this field is a TextInput. The admin adds a JavaScript calendar, and a shortcut for “Today”. Includes an additional invalid_date error message key.
The options auto_now_add, auto_now, and default are mutually exclusive. Any combination of these options will result in an error.
But that's not the cause of the issue you see. When you do this:
cp = CoursePurchase(course=page.course, user=request.user)
You are not retrieving anything from the database, but rather creating a new instance (in-memory only, not saved anywhere yet). To retrieve instances, you need to query the database properly:
cp = CoursePurchase.objects.get(course=page.course, user=request.user)
You can try like this.
cp = CoursePurchase.objects.get(course=page.course, user=request.user)

How to get the same date result from Model.objects.create and Model.objects.get in Django?

Given the following Django model:
from django.db import models
class SomeModel(models.Model):
date = models.DateField()
When I create an object with following code, type of date field is unicode
obj = SomeModel.objects.create(date=u'2015-05-18')
But when I get the same object from database, type of date field will be datetime.date
obj = SomeModel.objects.get(pk=obj.pk)
I know Django will transform u'2015-05-18' to a datetime.date object automatically, but why it returns the original unicode string with Model.objects.create()? is there a way to always get datetime.date from Model.objects.create() and Model.objects.get()?
Simply pass an datetime object to the create method:
from datetime import date
obj = SomeModel.objects.create(date=date(2015, 5, 18))
or
obj = SomeModel.objects.create(date=date.strftime('2015-05-18', '%y-%m-%d'))
There are two ways Django transforms the data in a model. The first, when saving the model the data is transformed to the correct data type and send to the backend. The data on the model itself is not changed. The second, when the data is loaded from the database, it is converted to the datatype that Django thinks is most appropriate.
This is by design: Django does not want to do any magic on the models itself. Models are just python class instances with attributes, so you are free to do whatever you want. This includes using the string u'2015-05-18' as a date or the string 'False' to store as True (yeah that's right).
The database cannot store dates as arbitrary data types, so in the database it is just the equivalent of a Python date object. The information that it used to be a string is lost, and when loading the data directly from the database with get(), the data is consistently converted to the most appropriate Python data type, a date.

Django - ValidationError on saving a model instance containing DateField

I'm still on this view. Now I have a ValidationError while trying to save the model instance. The error is:
Enter a valid date in YYYY-MM-DD format
The DateField is correctly filled, the type of instance passed to model is unicode. I have to do something like a cast from unicode to datetime or there's something I'm doing wrong before...?
This is the traceback.
Any idea?
Thanx
If you already know that the form is valid through form.is_valid(), consider working with cleaned_data instead of working directly with the request.POST:
if form.is_valid():
...
fattura.data = form.cleaned_data["data"]
fattura.diate = Decimal(form.cleaned_data["diate"])
...