At critify, we do a lot of copy & paste. Sometimes, that means copy & pasting a date from another site into a Django DateTimeField on our site. This can be tedious, because Django only supports a fixed number of strict input formats, while the actual input can at times be something quite freeform. So I decided that what was needed were date form fields that would make a good attempt at parsing the input.
Here’s what you need:
- python-dateutil, which provides the parser.
- This file, which implements DateTimeField and DateField form field classes which use python-dateutil to process the input.
With that available, the actual code is quite simple:
from djutils.forms.fields import formfield_callback class YourForm(ModelForm): formfield_callback = formfield_callback class Meta: model = YourModel
The formfield_callback will ensure that for every DateField or DateTimeField that your model has, the appropriate form field with dateutil-parsing support will be generated.
Of course, you can use these fields manually as well:
from django import forms from djutils.forms.fields import DateField class MyForm(forms.Form): std_date = forms.DateField() # < - Uses the standard DateField parsed_date = DateField() # <- Uses the custom DateField
This should work well enough; we can now put something like 8th of January into the form, and it’ll be parsed into the correct date.
“8th of January”? My site is in German! Fortunately, while not supporting it out of the box, python-dateutil is flexible enough to allow for internationalization as well. You need to get:
- Yet another file, which adds support for German date strings to python-dateutil (i.e. “Janauar”, “Montag”, ….). If you need to support a different language, you can use that file as a template.
The way internationalization is done with python-dateutil is that you implement a parserinfo class for a given language. We need to tell our custom form fields to use the German parserinfo provided by the file above:
from djutils.forms.fields import get_formfield_for from pyutils.date import GermanParserInfo class YourForm(ModelForm): def formfield_callback(field): # If it's a date-related field, get one of our custom form fields result = get_formfield_for(field, parserinfo=GermanParserInfo()) # Otherwise, use the default form field. return result or field.formfield() class Meta: model = YourModel
That’s basically it. You might want to create a base form class that you can inherit from for DRY purposes.
By the way, my module containing the German parser info also has a MultiParserInfo helper that may be useful to some:
This will give you a parser that supports both German date names, and the original English date names as a fallback. If you need to support even more languages, you could too: