Hello,
I would like to have a model field that saves durations as whole minutes:
class Example(models.Model):
duration = models.IntegerField(help_text="The duration in minutes.")
However, in the Django Admin I would like to represent the duration in HH:MM form and allow the user to enter durations in this form. For example, 90 minutes would be represented as 1:30 in a forms.CharField
. Entering and saving an input of 100:00 would save 6000 minutes.
To achieve this, I wrote a custom form field:
class ZeitspanneField(forms.Field):
def __init__(self, *, min_value=None, max_value=None, **kwargs):
# ...
super().__init__(**kwargs)
def prepare_value(self, value):
# Converts `int` to HH:MM strings.
if isinstance(value, int):
return minutes_to_HHMM(value)
# ...
return value
def to_python(self, value):
# Converts `value` (e. g. "1:30") into an integer.
# ...
return convert_HHMM_to_minutes(value)
def validate(self, value):
super().validate(value)
# ...
And, following the documentation, a custom model field:
class ZeitspanneModelField(models.IntegerField):
def formfield(self, **kwargs):
defaults = {"form_class": MyForms.ZeitspanneField}
defaults.update(kwargs)
return super().formfield(**defaults)
Using both in the updated model class:
class Example(models.Model):
duration = ZeitspanneModelField(help_text="The duration in minutes.")
The problem is: When I use this in the Django Admin (using class Example
with admin.TabularInline
), it doesn’t work: The input fields are rendered with HTML type="number"
, as if Example.duration
was still defined with models.IntegerField
instead of the ZeitspanneModelField
. The fields that should already have data are also empty, no value is rendered.
It looks as if the widget was taken from the base class of the model field (which is models.IntegerField
) rather than the default widget that comes with the form field (which should be text).
What am I doing wrong?