Forums

Problem with DateField in Django 2.0 and Posgres

I use type="date" in input tags for signal date input and trigger the date picker behaviour in browsers. All works well in my local test environment but when running on PythonAnywhere, it doesn't display correctly: it displays "dd / mm / yyyy" in the field area when the form loads instead of the stored or, if a new object, initial value.

The major difference between the two environments that I would think relevant is the DB which goes from sqlite3 to Posgres. However the values do get stored correctly, they just don't render when the form first loads.

The model field is: models.DateTimeField(blank=True, null=True) and the widget is: forms.DateInput(attrs={'type': 'date', 'class': 'form-control'})

When I inspect the page source it explains what the problem is but doesn't suggest a solution. In my test environment the tag is, correctly:

<input type="date" name="start_on" value="2018-04-11" class="form-control" id="id_start_on" />

In the live environment it is instead:

<input type="date" name="start_on" value="11/04/2018" class="form-control" id="id_start_on" />

can someone suggest why the two environments behave differently and how I can fix the live version?

Many thanks for your help

That's odd. What happens if you set the Django-wide data format by putting this in your settings.py?

DATE_FORMAT = "%Y-%m-%d"

Thanks Giles, tried it but no change unfortunately.

Here are my localisation setup in settings:

LANGUAGE_CODE = 'en-gb'
LOCALE_PATHS = (BASE_DIR + '/locale', )
DATE_FORMAT = "%Y-%m-%d"
TIME_ZONE = 'Europe/London'
USE_I18N = True
USE_L10N = True
USE_THOUSAND_SEPARATOR = True
USE_TZ = True

That doesn't look like the right format for specifying a date format: https://docs.djangoproject.com/en/2.0/ref/settings/#date-format

Hi Glen, you are of course right but unfortunately that didn't resolve it. I tried both DATE_FORMAT = 'Y-m-d' and DATE_FORMAT = 'd/m/Y' to check if it impacts how the value parameter in the input tag is interpreted but no change. Also tried SHORT_DATE_FORMAT.

Thanks

Ok, then I would start to suspect that the settings that you're setting are not actually the ones that your app is using. Make sure that those are the settings that are in place in the code that renders your input.

The mystery thickens...

When I bind the form in the django shell (inside PythonAnywhere) I get the right output. For example, for a particular objects stored in the DB:

<input type="date" name="start_on" value="2018-02-07" class="form-control" required id="id_start_on" />

However when I render the form through the live django instance I get instead:

<input type="date" name="start_on" value="07/02/2018" class="form-control" required id="id_start_on" />

...even though I'm printing the same form, bound to the same object, using the as_p() function from a python shell on the first case or view function in the second. Obviously settings.py is the same, the DB is the same in this case

That reinforces my guess that you're not actually running with the settings that you think you are. Are those settings you listed above in your project's settings.py? Are you sure they're not being overridden somewhere?

same exact file being referenced from python manage.py shell_plus --settings.... or inside the ....wsgi.py

Actually check the values of those settings in the code that is rendering the form. Based on the discussion so far, I'll bet that it's not what you expect. Then you just need to work out why they're different.

Thaks Glen. I've checked the values of USE_I18N, USE_L10N and both DATE_FORMAT and SHORT_DATE_FORMAT. These are identical across both environments (True, True, 'd/m/Y' and 'd/m/Y'). Also check MIDDLEWARE which again is identical.

Can you suggest any other settings that may play a part in creating the difference?

Thanks again

For what it is worth to others, I finally managed to fix the widgets by adding format="%Y-%m-%d" to the DateInput widget definitions. For example (in the form class):

start_on = forms.DateField(
    localize=True,
    widget=forms.DateInput(format = '%Y-%m-%d',attrs={'type': 'date', 'class': 'form-control'}),
)

Still unclear though why the same form rendering code behaves differently in the django shell and in the live website. Further investigations continued to indicate the settings are identical.

Thanks for the help!

for the sake of completeness, you did reload your webapp etc in between changes right?

also, i'm confused about what you checked for DATE_FORMAT and SHORT_DATE_FORMAT. You said that they are both 'd/m/Y'? Isn't that the wrong format?

Hi Conrad, yes that is correct I did reload each time. The format is correct in DATE_FORMAT and similar as was pointed out by Glenn earlier

OK, thanks! So, two oddities:

  • You were seeing different behaviour in local/shell vs the live site.
  • Putting the date format in the settings.py wasn't enough, you had to explicitly define it on the widgets.

Is that right?