你如何覆盖django将DurationField显示为字符串的方式?

时间:2017-12-01 12:40:31

标签: django

在我的表单中,我希望用户输入两部分时间... HH:mm但是在加载更新表单时,持续时间字段值将返回为HH:mm:ss

所以保存一个值时:

duration: 13:00

编辑表单时,初始数据为:

duration 13:00:00

保存时我得到ValidationError,因为这不是我想接受的格式。

            if ':' in duration:
                try:
                    (hours, minutes,) = duration.split(':')
                except ValueError:
                    self.add_error(
                        'duration',
                        _("Invalid duration: {}".format(duration))
                    )
                    return duration

有没有办法只为我展示HH:mm的所有地方显示DurationField格式,还是最好只在表单的初始数据中设置它?

1 个答案:

答案 0 :(得分:1)

如果您使用DurationField,为什么要添加验证? Django提供的验证应该有效,并且将接受'13:00'作为输入以及'13:00:00'。只需在您的小部件中添加一个占位符文本,例如'13:00',这样您的用户就知道要输入什么,但不要通过禁止'13:00:00'来添加障碍。

如果您在ModelForm课程中使用Meta

widgets = {'duration': TextInput(attrs={'placeholder': '13:00'})}

在内部,您的持续时间保存为datetime.timedelta,因此您只需验证您要接受的有效持续时间(例如不超过12小时......)。无论您需要输出duration,都可以根据需要对其进行格式化(例如,请参阅主题上的this SO thread)。

要覆盖输入字段中值的显示方式,您应该继承forms.DurationField

from django.utils.duration import _get_duration_components

def hhmm_duration_string(duration):
    days, hours, minutes, seconds, microseconds = 
       _get_duration_components(duration)

    string = '{:02d}:{:02d}'.format(hours, minutes)
    return string

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