Issue
My model has a DurationField which is editable in Django Admin. I don't like how Django (inheriting its behavior from Python) displays negative durations, so I've tried to monkey patch it:
test = lambda: duration.duration_string(datetime.timedelta(seconds=-5)) == \
'-00:00:05'
if not test():
_duration_string = duration.duration_string
def duration_string(duration):
if duration.days < 0:
return '-' + _duration_string(-duration)
return _duration_string(duration)
duration.duration_string = duration_string
assert test()
This code gets run as part of my AppConfig.ready()
method.
However, in Admin, the field still displays values formatted the default way. Is there some other way to customize how a DurationField's value is rendered in Admin?
At @Mehak's suggestion I tried the solution in this question. In fact, I tried just making a custom field that just bombs the program:
class CustomDurationField(models.DurationField):
def value_to_string(self, obj):
raise Exception()
def __str__(self):
raise Exception()
No exception is raised when viewing or editing the field, after making and applying the migration of course.
Solution
This answer led me on the right track. After performing the monkey patch, I had to define a custom model field that uses a custom form field...
import datetime
from django import forms
from django.db import models
from django.utils import duration
class CustomDurationFormField(forms.DurationField):
def prepare_value(self, value):
if isinstance(value, datetime.timedelta):
return duration.duration_string(value)
return value
class CustomDurationField(models.DurationField):
def formfield(self, **kwargs):
return super().formfield(**{
'form_class': CustomDurationFormField,
**kwargs,
})
If you don't want to monkey patch Django's django.utils.duration.duration_string
, then you would just change CustomDurationFormField.prepare_value
to call a separately defined version of it.
I'm not entirely sure why it requires so much effort to do this, but there it is.
Answered By - rgov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.