Django ModelForm中的DurationField格式

Django ModelForm中的DurationField格式,django,django-forms,Django,Django Forms,我有一个Django模型,其中包含一个持续时间字段: class Entry(models.Model): duration = models.DurationField() 我想使用ModelForm为这个模型呈现一个表单: class EditEntryForm(forms.ModelForm): class Meta: model = Entry fields = ['duration'] 这一切都在起作用。但是,如果编辑现有模型,文本框

我有一个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

在渲染模型时,我已经使用了一个自定义模板过滤器,我只是不知道如何更改表单的渲染方式


谢谢

您应该能够通过为字段提供自定义小部件来实现这一点:

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()
        }
然后在字段中指定此小部件:

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()
        }

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

在我的例子中,我需要删除毫秒,所以我按照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__'

这看起来是正确的,但不幸的是,
value
在到达
\u format\u value
方法时是一个
str
对象。我想我可以解析字符串,并重新格式化,但这比访问实际的持续时间要难看一点哦,那时我还没意识到它是一个字符串。如果您想访问实际值,那么您可以在子类的
DurationField
prepare\u value
value方法中执行相同的逻辑。我已经编辑了一些应该实际工作的答案-同意您的观点,但是解析字符串并不理想。我继续制作子类
DurationField
重写
prepare\u值
方法,该方法工作正常,允许您访问
timedelta
对象。然而,我接受你的答案,因为它是有效的,让我走上了正确的轨道。谢谢