ModelForm中的DurationField格式

时间:2015-10-12 10:01:53

标签: django django-forms

我有一个包含持续时间字段的Django模型:

class Entry(models.Model):
    duration = models.DurationField()

我想使用ModelForm为这个模型渲染一个表单:

class EditEntryForm(forms.ModelForm):
    class Meta:
        model = Entry
        fields = ['duration']

哪一项都有效。但是,如果编辑现有模型,则在文本框中呈现的持续时间的格式为HH:MM:SS

我永远不会处理一个多小时的持续时间。如何更改Django如何将表单中的此字段格式化为MM:SS

我在渲染模型时已经有了一个自定义模板过滤器,我无法弄清楚如何更改表单的呈现方式。

由于

2 个答案:

答案 0 :(得分:6)

您应该可以通过为字段提供自定义窗口小部件来完成此操作:

from django.forms.widgets import TextInput
from django.utils.dateparse import parse_duration

class DurationInput(TextInput):

    def _format_value(self, value):
        duration = parse_duration(value)

        seconds = duration.seconds

        minutes = seconds // 60
        seconds = seconds % 60

        minutes = minutes % 60

        return '{:02d}:{:02d}'.format(minutes, seconds)

然后在字段上指定此小部件:

class EditEntryForm(forms.ModelForm):
    class Meta:
        model = Entry
        fields = ['duration']
        widgets = {
            'duration': DurationInput()
        }

当然,如果您提供超过一小时的持续时间,这将导致奇怪......

答案 1 :(得分:2)

在我的情况下,我需要删除毫秒,所以我做了MichaelM建议的

# -*- coding: utf-8 -*-

import datetime

from django import forms

from harvests.models import Harvest


def duration_string(duration):
    # Removing the milliseconds of the duration field
    days = duration.days
    seconds = duration.seconds
    microseconds = duration.microseconds

    minutes = seconds // 60
    seconds = seconds % 60

    hours = minutes // 60
    minutes = minutes % 60

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

    return string


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


class HarvestForm(forms.ModelForm):
    work_time_interval = CustomDurationField()

    class Meta:
        model = Harvest
        fields = '__all__'