Making Django forms.DateField show use local date format
datefield, django, forms, strftime
Solution
Granted, I'm not a django/python Jedi, but...
I don't think there is anything wrong with your approach. It is a clean read.
You might not need to create your own widget just to render the date in the proper format on the first form display. Just use the `format` parameter for the `DateInput` widget and you should be OK. So in your MyDateField class I would just do:
class MyDateField(forms.DateField):
widget = forms.DateInput(format="%d/%m/%Y")
def __init__(self, *args, **kwargs):
super(MyDateField, self).__init__(*args, **kwargs)
self.input_formats = ("%d/%m/%Y",)+(self.input_formats)
You could use `formfield_callback` (See the accepted answer for this distantly related question), meaning:
def customize_fields(f):
if isinstance(f, DateTimeField):
datetime_field=forms.DateTimeField(widget=
forms.DateInput(format='%d/%m/%Y %h:%i'))
date_field.input_formats = ("%d/%m/%Y %h:%i",)+
(date_field.input_formats)
return datetime_field
elif isinstance(f, DateField):
date_field=forms.DateField(widget=
forms.DateInput(format='%d/%m/%Y'))
date_field.input_formats = ("%d/%m/%Y",)+
(date_field.input_formats)
return date_field
else:
return f.formfield()
class MyModelForm(forms.ModelForm):
formfield_callback = customize_fields
class Meta:
model = ...
Doing that completely eliminates the need for your `MyDateField` class, but might introduce - if you want every single form class to call `customize_fields` - the need for a ModelForm descendent, implementing `formfield_callback=customize_fields` as the new base for all your form classes.
My problem with using the `formfield_callback` mechanism is two-fold:
It is less readable and relies in knowledge of the inner workings of ModelForms. I can't find actual documentation on formfield_callback anywhere...
If you ever need to redefine a model field in a ModelForm, say to make the field not required for that particular instance of the form, like so:
class MyModelForm(forms.ModelForm):
formfield_callback = customize_fields
foo = forms.DateField(required=false)
class Meta:
model = Bar
you are overwriting the form field returned by customize_fields, hence completely losing the customization.
I think your approach is more readable.
Problem
I'm trying to find an easy way to build forms which show dates in the Australian format (dd/mm/yyyy). This was the only way I could find to do it. It seems like there should be a better solution. Things to note: - Created a new widget which renders date value in dd/mm/yyyy format - Created new date field to prepend the locate date format string to the list of values it tries to use I imagine the ideal solution would be a datefield which automatically localised but that didn't work for me (strftime didn't seem to be unicode friendly but I didn't try very hard) Am I missing something? Is there a more elegant solution? Is this a robust approach? ``` from models import * from django import forms import datetime class MyDateWidget(forms.TextInput): def render(self, name, value, attrs=None): if isinstance(value, datetime.date): value=value.strftime("%d/%m/%Y") return super(MyDateWidget, self).render(name, value, attrs) class MyDateField(forms.DateField): widget = MyDateWidget def __init__(self, *args, **kwargs): super(MyDateField, self).__init__(*args, **kwargs) self.input_formats = ("%d/%m/%Y",)+(self.input_formats) class ExampleForm(ModelForm): class Meta: model=MyModel fields=('name', 'date_of_birth') date_of_birth = MyDateField() ```