制作Django forms.DateField显示使用本地日期格式

oli*_*rge 7 forms django strftime datefield

我正试图找到一种简单的方法来构建以澳大利亚格式显示日期的表格(年/月/日).这是我能找到的唯一方法.似乎应该有一个更好的解决方案.

注意事项:

  • 创建了一个新的小部件,以dd/mm/yyyy格式呈现日期值
  • 创建新的日期字段,以将定位日期格式字符串添加到它尝试使用的值列表中

我想,理想的解决方案是一个自动本地化的日期字段,但对我来说不起作用(strftime似乎不是unicode友好但我没有努力尝试)

我错过了什么吗?有更优雅的解决方案吗?这是一种强有力的方法吗?

from models import *
from django import forms
import datetime

class MyDateWidget(forms.TextInput):

    def render(self, name, value, attrs=None):

            if isinstance(value, datetime.date):
                    value=value.strftime("%d/%m/%Y")

            return super(MyDateWidget, self).render(name, value, attrs)


class MyDateField(forms.DateField):

    widget = MyDateWidget

    def __init__(self, *args, **kwargs):
            super(MyDateField, self).__init__(*args, **kwargs)
            self.input_formats = ("%d/%m/%Y",)+(self.input_formats)


class ExampleForm(ModelForm):
    class Meta: 
            model=MyModel
            fields=('name', 'date_of_birth')

    date_of_birth = MyDateField()
Run Code Online (Sandbox Code Playgroud)

cet*_*eek 10

当然,我不是django/python Jedi,但......

我不认为你的方法有任何问题.这是一个干净的阅读.

您可能不需要创建自己的小部件,只是为了在第一个表单显示上以正确的格式呈现日期.只需使用小部件的format参数DateInput,你应该没问题.所以在你的MyDateField类中,我会这样做:

class MyDateField(forms.DateField):

    widget = forms.DateInput(format="%d/%m/%Y")

    def __init__(self, *args, **kwargs):
        super(MyDateField, self).__init__(*args, **kwargs)
        self.input_formats = ("%d/%m/%Y",)+(self.input_formats)
Run Code Online (Sandbox Code Playgroud)

你可以使用formfield_callback(参见这个远程相关问题的接受答案),意思是:

def customize_fields(f):
    if isinstance(f, DateTimeField):
        datetime_field=forms.DateTimeField(widget=
            forms.DateInput(format='%d/%m/%Y %h:%i'))
        date_field.input_formats = ("%d/%m/%Y %h:%i",)+
            (date_field.input_formats)
        return datetime_field
    elif isinstance(f, DateField):
        date_field=forms.DateField(widget=
            forms.DateInput(format='%d/%m/%Y'))
        date_field.input_formats = ("%d/%m/%Y",)+
            (date_field.input_formats)
        return date_field
    else:
        return f.formfield()

class MyModelForm(forms.ModelForm):
    formfield_callback = customize_fields

    class Meta:
        model = ...
Run Code Online (Sandbox Code Playgroud)

这样做完全消除了对你的MyDateField类的需要,但可能会介绍 - 如果你想要每个单独的表单类调用customize_fields- 需要一个ModelForm后代,实现formfield_callback=customize_fields作为所有表单类的新基础.

我使用该formfield_callback机制的问题有两个:

  1. 它的可读性较差,并且依赖于对ModelForms内部工作的了解.我无法在任何地方找到关于formfield_callback的实际文档......

  2. 如果您需要在ModelForm中重新定义模型字段,请说明该表单的特定实例不需要该字段,如下所示:

       class MyModelForm(forms.ModelForm):
           formfield_callback = customize_fields
           foo = forms.DateField(required=false)
    
           class Meta:
               model = Bar
    
    Run Code Online (Sandbox Code Playgroud)

    您正在覆盖customize_fields返回的表单字段,因此完全失去了自定义.

我认为你的方法更具可读性.


ala*_*lan 6

我之前使用过这个简单的方法:只需在Form的init中设置DateField.widget的'format'属性:

    class ExampleForm(ModelForm):

        class Meta:
            model = MyModel

        def __init__(self, *args, **kwargs):
            super(ModelForm, self).__init__(*args, **kwargs)
            self.fields['date_of_birth'].widget.format = '%d/%m/%Y'

            # at the same time, set the input format on the date field like you want it:
            self.fields['date_of_birth'].input_formats = ['%d/%m/%Y']
Run Code Online (Sandbox Code Playgroud)