I'm trying to specify a default date in a Django model, for example:
from datetime import date
class A(models.Model):
date = models.DateField(default=date.today())
This works and I can see the default date in a ModelForm, but when I change the form input_format to %d-%m-%Y, the default date never appears in the field.
I've also tried:
from datetime import date
class A(models.Model):
date = models.DateField(default=date.today().strftime('%d-%m-%Y'))
This doesn't work either. Can anyone help me?
There are two problems here:
the DateField(default=today.today()) will not work, since then the function will be evaluated eagerly, and then the default value is thus the result of that function call. As a result the default value is not calculated when constructing a new object, and hence eventually will be different; and
the representation of a DateField. Now the model layer does not specify a representation, it only specifies how to store values in the database, and defines functions on a model.
We can solve the first problem by passing a reference to the today function, like:
from datetime import date
class A(models.Model):
date = models.DateField(default=date.today) # no ()
As for the representation, you should specify the format in the template, for example with the date template filter [Django-doc], like:
<!-- template.html -->
{{ some_a.date|date:'d-m-Y' }}
Or in a form with:
# app/forms.py
class AForm(ModelForm):
date = DateField(input_formats=['%d-%m-%Y'])
class Meta:
model = A
You can use the DATE_INPUT_FORMATS setting in your Django project settings, this will allow you to make date.today().strftime('%d-%m-%Y') be accepted by your model field; however, the DateField is stored in your database as the native column of the same type and not as a string with a specific format. There is a difference between storing the data and representing it in your forms, templates or DRF serializers. I really recommend keeping the default format for the database and present the data in the format you want by using the DATE_FORMAT setting to d-m-Y that will take care of presenting your dates in that format as long as the USE_L10N setting is False.
if you want to use the same format for display and input, you have to specify input_formats and format(in widget) respectively. for example
class OrderForm(forms.ModelForm):
deadline = forms.DateTimeField(
input_formats=['%d/%m/%Y %I:%M %p', ], # input format
widget=forms.DateTimeInput(format="%d/%m/%Y %I:%M %p"), # initial display format
)
Related
I have a Django project, and I want to save created_at datetime in the database. I generate datetime.now with jdatetime (or Khayyam) python package and try to save this in DateTimeField. But sometimes it raises error because the Gregorian(miladi) date of the entry does not exist. what can I do about this?
In my idea, you can save two model fields.
One is DateTimeField contains gregorian datetime, and
another one, CharField contains converted Jalali to a String value and save it.
The DateTimeField for functionality, e.g., filter between to datetime.
The StringField for representing in response(without overload).
I want to implement a database search and I need to filter queryset by date that contains search request. The problem is that users will see formatted date (like dd.mm.yyyy) and will expect search to see it the same way, but default __contains consider date in yyyy-mm-dd format. How can I apply filter to DateField before using __contains? I need a way using django orm because otherwise it will be too long (not using sql).
I tried to set DATE_FORMAT = 'd.m.Y' to satisfying format but it has no effect (even setting USE_L10N = False)
Also thought about creating custom lookup but not sure how to implement it
I need to apply __contains to all model fields, so I can't just reformat search value
You can Annotate the date attribute to a CharField and execute your filter on Annotated attribute.
from django.db.models import Func, F, Value, CharField
queryset.annotate(string_date=Func(
F('YOUR_DATE_FIELD'),
Value('YOUR OUTPUT FORMAT'),
output_field=CharField(),
function='to_char')
).filter(string_date__contains=INPUT_DATE)
I need to filter another datetime field through a datetime field, but I just need to compare date. How to implement it by F expression?
F expression does not seem to format fields
My model is:
class Test():
date1 = models.DateTimeField()
date2 = models.DateTimeField()
I just need to compare date, not time.
Test.objects.filter(Q(date2__gt=F('date1')))
It keeps comparing datetime. That's not what I want. I just want to compare date. As a Django rookie, I can't find a solution.
I used time zone and Mysql, and I don't want to modify them.
You can use the __date field lookup for this.
In your case:
Test.objects.filter(Q(date2__date__gt=F('date1__date')))
Can give you the desired result.
The __date field lookup helps to extract only the date from the datetime field.
But make sure that you are using Django>1.9, for older versions of Django, you need to use other methods
class Test(Model):
time = DateTimeField()
# ...
row = Test.select()[0]
test.time
This returns a string that looks like this: 2017-01-23 01:01:39+01:00. How can I get it as a datetime object instead? Do I have to parse it manually?
Also I would be interested if there is any documentation on how to use the DateTimeField. The official documentation doesn't have anything on it.
Are you using SQLite? If so, SQLite doesn't have a dedicated datetime type, so datetimes are stored as strings in the DB. What peewee will do is recognize certain datetime formats coming out of the DB and convert them to datetime objects. What you need to do is ensure that either:
When you create/save your object, that you assign a datetime object to the field.
When reading back pre-existing data, that the data is in a recognized format.
The formats peewee supports out-of-the-box for datetime field are:
YYYY-mm-dd HH:MM:SS.ffffff
YYYY-mm-dd HH:MM:SS
YYYY-mm-dd
It looks like your has zone info. I'd suggest converting to UTC and dropping the zone info. That should fix it.
Have you tried adding a default like this?
time = DateTimeField(default=datetime.datetime.now())
Or when adding an entry add it as a datetime.datetime object directly:
test = Test(....., time=datetime.datetime.strptime("2018-3-15", '%Y-%m-%d'))
In the second case you don't need to specify anything in the class definition...
I am working on a form and have a date field.
I want to save different date format for date field instead django used.
I am getting "01-jan-2016" date and want to save as it is in my database.when i am trying to save this same format is raise an error
[u"'07-Dec-2016' value has an invalid date format. It must be in YYYY-MM-DD format."].
I know this type of question asked already but they do not solve my problem.
views.py
post_date = request.POST['date']
lead_obj = CustomerLeads.objects.create(posting_date = post_date)
my models.py
class Leads(models.Model):
customer_name = models.CharField(max_length=50,null=True, blank=True)
title = models.CharField(max_length=100, null=True, blank=True)
posting_date = models.DateField()
Mysql
The DATE type is used for values with a date part but no time part.
MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The
supported range is '1000-01-01' to '9999-12-31'.
Postgresql
Date and time input is accepted in almost any reasonable format,
including ISO 8601, SQL-compatible, traditional POSTGRES, and others.
For some formats, ordering of day, month, and year in date input is
ambiguous and there is support for specifying the expected ordering of
these fields. Set the DateStyle parameter to MDY to select
month-day-year interpretation, DMY to select day-month-year
interpretation, or YMD to select year-month-day interpretation.
The table at the link shows that postgresql accept the format that you are looking for. But how is it stored? Let's try an insert
INSERT INTO stackoverflow_heatwatchlist(next_date_from, next_date_to)
VALUES('1999 Jan 05','2001 Jun 06');
And when you select, what you get is '2001-06-06' and '1999-01-05'
SQlite
Here you can insert in any format you want and it will be saved exactly as you entered, that's because sqlite does not enforce any strict type checking. Types in sqlite are purely cosmetic. but django has a different opinion on the matter and will not let you divert too much from the standard formats.
SQL Server
A lot of flexibility in how the data is accepted for insert. Refer to the table at the link. But how is it stored? '1999-01-05'
In conclusion
How the date is stored in the table is totally irrelevent, all that matters is what formats are accepted for input and how it's displayed. And that's where django's and python's excellent date and time formats come into play.
If you are not happy with them, you have two choices. The first is to store dates and times as unix timestamps and do all the formatting yourself, all you need is a little math really - a fairly common practice.
The second is to use CharField for storing your data but this is not very usefull. Not only do you have to do all the formatting and input validation yourself, any calculation would involve a lot of string processing and casting.
Try to add '%d-%b-%Y' to DATE_INPUT_FORMATS in your project settings.
In your views.py try this:
from dateutil import parser
d = parser.parse("07-December-2016")
print d
d = d.strftime("%d-%b-%Y")
print d
Output:
2016-12-07 00:00:00
07-Dec-2016
It will handle various formats.