【问题标题】:DurationField format in a ModelFormModelForm 中的 DurationField 格式
【发布时间】:2015-10-12 10:01:53
【问题描述】:

我有一个包含持续时间字段的 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

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

谢谢

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

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

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

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

    【讨论】:

    • 这看起来在正确的轨道上,但不幸的是,value 在它到达_format_value 方法时是一个str 对象。我想我可以解析字符串并重新格式化,但这比访问实际持续时间有点丑
    • 哦,那时我还没有意识到它是一个字符串。如果要访问实际值,则可以在子类DurationFieldprepare_value 值方法中执行相同的逻辑?
    • 我已经编辑了应该实际工作的答案 - 同意你的观点,但是解析字符串并不理想。
    • 我创建了一个子类 DurationField,它覆盖了 prepare_value 方法,该方法工作正常,并允许您访问 timedelta 对象。但是,我接受您的回答,因为它有效并使我走上正轨。谢谢!
    【解决方案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__'
    

    【讨论】:

      猜你喜欢
      • 2016-01-11
      • 2022-11-17
      • 2015-06-07
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      相关资源
      最近更新 更多