【问题标题】:Django DateField: enter a date without a year to mean this yearDjango DateField:输入没有年份的日期来表示今年
【发布时间】:2021-06-10 06:14:29
【问题描述】:

我想允许在DateField 中输入没有年份的日期来表示实际年份。像 "10.6." 应该表示 2021 年 6 月 10 日,因为在撰写本文时是 2021 年。以下DATE_INPUT_FORMATS 没有删减:

DATE_INPUT_FORMATS = ('%d.%m.%y', '%d.%m.%Y', '%Y-%m-%d', '%d.%m.')

这确实允许这样的输入,但年份是 0000 年 6 月 10 日;不是我的目标。

有什么建议吗?

【问题讨论】:

  • 您使用的是Form吗?
  • 不,我只是在使用管理界面。
  • 您还可以更改管理界面使用的表单。
  • 参见docs.djangoproject.com/en/3.2/ref/contrib/admin/… 默认是自动创建的ModelForm,但您可以定义自定义表单,然后在ModelAdmin 中为该模型链接到该表单。跨度>
  • 实际上这个问题是错误的,你不能在 django DateField 中做这样的事情是的,你可以制作表格来连接并保存年份,如下代码所示,但你不能改变 django DateField

标签: python django datefield


【解决方案1】:

这确实允许这样的输入,但年份将是 0000 年 6 月 10 日。

据我所知,应该是 1900 年 6 月 10 日,但这当然无关紧要。

您可以在您的Form 中实现clean_<i>fieldname</i>,例如:

从 django 导入表单 现在从 django.utils.timezone 导入

class MyForm(forms.Form):
    day = forms.DateField()

    def clean_day(self):
        day = self.cleaned_data['day']
        if day.year == 1900:
            day = day.replace(year=now().year)
        return day

因此,在 clean 方法中,我们检查年份是否为 1900,如果是,我们将其替换为当前年份。

当然如果用户输入10.6.1900,也会被替换为2021年6月10日。因此我们无法知道是'%d.%m'模式还是%d.%m.%y模式解析的。

【讨论】:

    【解决方案2】:

    仍然接受 1900 年作为有效输入的更强大的解决方案是覆盖表单 DateField 本身。尽管这带有一个警告,即您无法轻松地与我们可以在设置中设置的输入格式集成,因此如果您想要格式本地化,这不是很合适:

    import datetime
    
    from django import forms
    from django.core.exceptions import ValidationError
    
    
    class YearOptionalDateField(forms.DateField):
        yearless_formats = ['%d.%m.']
    
        def to_python(self, value):
            try:
                return super().to_python(value)
            except ValidationError:
                value = value.strip()
                for format in self.yearless_formats:
                    try:
                        date = self.strptime(value, format)
                        return date.replace(year=datetime.datetime.now().year)
                    except (ValueError, TypeError):
                        continue
                raise
    
    
    class YourForm(forms.Form):
        date = YearOptionalDateField()
    
    
    # Test
    form = YourForm({'date': '10.6.'})
    print(form.is_valid())  # True
    print(form.cleaned_data['date'])  # 2021-06-10
    

    注意:删除 '%d.%m.' 以及您可能拥有的 DATE_INPUT_FORMATS 中的任何类似格式,以使其正常工作。

    【讨论】:

      猜你喜欢
      • 2011-03-05
      • 2011-01-11
      • 2010-11-14
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多