【问题标题】:How can I get the Django SplitDateTimeWidget to recognize AM/PM inputs?如何让 Django SplitDateTimeWidget 识别 AM/PM 输入?
【发布时间】:2011-06-08 06:39:35
【问题描述】:

我这辈子都不知道如何让SplitDateTimeWidget (link to ref doc) 识别 AM/PM 输入。

模板样式的输入我都试过了:

widgets={'start_datetime':forms.SplitDateTimeWidget(time_format='h:i A')}

以及标准 Python 时间输入 (suggested here):

widgets={'start_datetime':forms.SplitDateTimeWidget(time_format='%I:%M %p')}

如您所料,start_datetime 在我的模型中是 DateTimeField

start_datetime=models.DateTimeField('Start', default=datetime.now())

我所做的一切似乎都无法通过验证——我一直在该字段中收到错误。有什么建议?我现在已经搜索了2个小时无济于事。如果我坚持使用 24 小时制或省略 AM/PM 部分,我可以让它验证,但我宁愿能够正确解释 AM/PM。

谢谢

【问题讨论】:

  • 经过大量研究,我意识到 time_format 根本不是我想要的。 time_format 仅指定默认表单值的外观——而不是输入数据的解析方式。

标签: python django datetime django-forms django-widget


【解决方案1】:

你可以直接覆盖django.contrib.admin.widgets.AdminSplitDateTime

这是代码:

class CustomAdminSplitDateTime(AdminSplitDateTime):
def __init__(self, attrs=None):
    widgets = [AdminDateWidget, AdminTimeWidget(attrs=None, format='%I:%M %p')]
    forms.MultiWidget.__init__(self, widgets, attrs)

现在你可以按如下方式使用它:

class MyForm(forms.ModelForm):

  class Meta:
    model=MyModel
    exclude=()
    start_datetime= forms.DateField(
        widget=CustomAdminSplitDateTime()
    )
    end_datetime= forms.DateField(
        widget=CustomAdminSplitDateTime()
    )

不要忘记将时间格式添加到设置文件中支持的格式中,例如:

TIME_INPUT_FORMATS = [
    '%I:%M %p',
    '%H:%M:%S',
    '%H:%M:%S.%f',
    '%H:%M'
]

【讨论】:

    【解决方案2】:

    最终,在对SplitDateTimeWidget 的源代码进行了大量研究之后,我没有看到将input_time_formats 传递到小部件的方法。也许有一种方法(我不太了解字段和小部件之间的共同血统,无法确定一种或另一种方式),但我找不到它。

    但是,我能够通过覆盖字段并在 ModelForm 中使用 SplitDateTimeField 来使其工作(模型中的原始字段为 DateTime 类型)。然后我需要将DateTimeSplitDateTimeField 传递回原始模型,因为表单字段和模型字段在我覆盖它之后没有链接。

    class MyForm(forms.ModelForm):
      start_datetime=forms.SplitDateTimeField(input_time_formats=['%I:%M %p'])
      end_datetime=forms.SplitDateTimeField(input_time_formats=['%I:%M %p'])
    
      class Meta:
        model=MyModel
        exclude=('start_datetime','end_datetime')
    
      def clean(self):
        self.instance.start_datetime=self.cleaned_data.get('start_datetime')
        self.instance.end_datetime=self.cleaned_data.get('end_datetime')
    

    【讨论】:

    • 这是否意味着如果没有您所做的更改,此处的代码将不起作用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 2016-03-31
    • 2022-01-19
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2014-12-31
    相关资源
    最近更新 更多