Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change format for Duration field in django admin

I'm using django DurationField in a model to calculate the time difference between two DateTimeField.

On the admin site for that model, the field shows up like this:

# short duration
Cumulative Total time:   0:51:33
# longer duration
Cumulative Total time:   2 days, 3:10:21

Is it possible to change the format for this field to the below given format?

Cumulative Total time:   2 days, 3 hours, 10 minutes, 21 seconds
like image 397
Mehak Avatar asked Aug 09 '18 15:08

Mehak


People also ask

How do I change the date format in Django admin?

Changing django admin default formats could be done changing the django locale formats for every type you want. Put the following on your admin.py file (or settings.py) to change datetime default format at your django admin. It will change the ModelAdmin's datetime formats on that file (or whole site if in settings).

What is duration field in Django?

DurationField is a field for storing periods of time – modeled in Python by timedelta. When used on PostgreSQL, the data type used is an interval and on Oracle the data type is INTERVAL DAY(9) TO SECOND(6). Otherwise, a bigint of microseconds is used.

How do I make a field optional in Django admin?

You would have to add blank=True as well in field definition. If the model field has blank=True, then required is set to False on the form field. Otherwise, required=True.


1 Answers

The DurationField has the following code that relates to formatting:

...
from django.utils.duration import duration_string
...

class DurationField(Field):
    ...
    def value_to_string(self, obj):
        val = self.value_from_object(obj)
        return '' if val is None else duration_string(val)

and the function duration_string looks like this:

def duration_string(duration):
    """Version of str(timedelta) which is not English specific."""
    days, hours, minutes, seconds, microseconds = _get_duration_components(duration)

    string = '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds)
    if days:
        string = '{} '.format(days) + string
    if microseconds:
        string += '.{:06d}'.format(microseconds)

    return string

One solution is to create your custom field that overrides the one method listed above:

from django.utils.duration import _get_duration_components

class CustomDurationField(DurationField):
    def value_to_string(self, obj):
        val = self.value_from_object(obj)
        if val is None:
            return ''

        days, hours, minutes, seconds, microseconds = _get_duration_components(val)
        return '{} days, {:02d} hours, {:02d} minutes, {:02d}.{:06d} seconds'.format(
            days, hours, minutes, seconds, microseconds)

You would need to tweak the exact output to fit your requirements.

like image 192
Ralf Avatar answered Sep 30 '22 07:09

Ralf