24
votes

Is there any way I can get django to store my data in postgresql as 'dd-mm-yyyy' (if required) and have the django forms validate for 'dd-mm-yyyy'?

(I have tried without much success things like:

DATE_INPUT_FORMATS = ('%d-%m-%Y')
USE_I18N = True
USE_L10N = True

And done a lot of googling but no success :(

7

7 Answers

46
votes

The problem turned out to be that I needed both the ISO and UK date formats in the settings.py file like so:

DATE_INPUT_FORMATS = ('%d-%m-%Y','%Y-%m-%d')

and then the forms.py adjusted to the following:

class ClientDetailsForm(ModelForm):
    date_of_birth = DateField(input_formats=settings.DATE_INPUT_FORMATS)
    class Meta:
        model = ClientDetails

Why USE_L10N = True can't just do this I don't know!

[Thanks to this and this]

22
votes

DATE_INPUT_FORMATS in settings.py has no effect with USE_I18N = True. This is because django will load specific format for active locale. Django ships with format definitions for many different locales.

You can override django default format definitions:

mysite/
    formats/
        __init__.py
        en/
            __init__.py
            formats.py

As described in django documentation: Creating custom formats file

13
votes

In Sevenearths answer there's the comment

Why USE_L10N = True can't just do this I don't know!

The documentation says that USE_L10N = True is the default setting, but to get UK dates to work the LANGUAGE_CODE must also be changed from its default setting of en-us to en-GB.

Once changed, date fields automatically accept the formats "dd/mm/yyyy" and "yyyy-mm-dd" (and possibly others, I've not tested them all) without needing to set input_formats = settings.DATE_INPUT_FORMATS in every form date field.

3
votes

This might not be the answer to the exact question, but since I got here... I would suggest using a date widget, and let Django save the date the way it understands it. Define the field in your form like so:

import datetime
from django import forms

def last_years():
    first_year = datetime.datetime.now().year - 6
    return list(range(first_year + 7, first_year, -1))

class MyForm(forms.Form):
    # This is it... it's user friendly, and can't go wrong parsing it
    date = forms.DateField(widget=forms.SelectDateWidget(years = last_years()))

If you got it into a date field of the Django Model, then the only problem left would be format the output representation. Am I right?

2
votes

This works for me

date_of_birth = forms.DateField(
    localize=True,
    widget=forms.DateInput(format = '%Y-%m-%d',attrs={'type': 'date'}),
)
2
votes

I used below code that worked on Both Add and Edit Form Case.

in settings.py

DATE_INPUT_FORMATS = ('%d/%m/%Y','%d-%m-%Y','%Y-%m-%d')

in forms.py

class MyModelForm(forms.ModelForm):
    issue_date = forms.DateField(widget=forms.DateInput(format = '%d/%m/%Y'), input_formats=settings.DATE_INPUT_FORMATS)
0
votes

I would overwrite the DateTimeField put my our logic. It doesn't matter how postgresql is storing it, you can format it how ever you want.

Docs: http://docs.djangoproject.com/en/dev/ref/models/instances/