Django DurationField for only hours and minutes?

Hi everyone! I am working with a ModelForm where I have a field that is stored in the database as a DurationField

Now on user input, when a user enters 1:30 I would like this to register as 1 hour and 30 minutes, but the DurationField stores this in the database as 00:01:30 which is 1 minute and 30 seconds.

When I go into my django shell, I see the output of the field as datetime.timedelta(seconds=90) I am trying to figure out a way to convert this to either datetime.timedelta(minutes=90) or even parse 00 on the end of input just to store this correctly in the DB

I’m not sure why the timedelta defaults to seconds ?

I’ve never worked with a DurationField field before, and appreciate any guidance

It might be helpful if you posted the relevent code / templates / settings / whatever that is handling this field.

I’m Just using a simple crispy form using a DurationField which just renders in the form as a text field.

class TimeForm(ModelForm):
    setup_duration = forms.DurationField(required=False)

I attempted to build a custom parser such as…

def duration_string(duration):

    days = duration.days
    seconds = duration.seconds

    minutes = seconds // 60

    hours = minutes // 60
    minutes = minutes % 60

    dur_string = f'{hours}:{minutes}:00'
    if days:
        dur_string = 'f{days} + dur_string'
    return dur_string

class CustomDurationField(forms.DurationField):
    def prepare_value(self, value):
        if isinstance(value, datetime.timedelta):
            return duration_string(value)
        return value

class TimeForm(ModelForm):
    setup_duration = CustomDurationField()

But when a user inputs 1:30 into the form field it still saves in the DB DurationField as minutes:seconds, which I am looking for hours:minutes.

The above user input example of 1:30 would store in my DB as datetime.timedelta(seconds=90), which I need it stored as datetime.timedelta(minutes=90)

Perhaps it would make more sense to store the number of minutes in the DB? But you would need extra logic to handle data coming from the form.

Or maybe something like custom clean_duration method that would convert the entered time into hours and minutes?

A forms.DurationField uses the parse_duration method to convert the entered data into a Duration.

This gives you a couple options:

  • As mentioned above, you could do a clean_setup_duration method to re-parse the entered value.
  • You could create a custom DurationFieldish class that implements a custom to_python method.
  • You could change the form field type to a CharField, and perform the parsing yourself based on your requirements.