1

默认情况下,Django 将日期/时间显示为类似May 13th, 2010, 4:01 p.m.. 我还配置了一个 jQuery日历插件(我使用dateFormat: "MM d, yy", timeFormat: "h:mm tt"并修改了 JavaScript 源代码以输出a.m.andp.m.而不是AMand PM)来以相同的格式显示日期/时间。

但是表单验证(默认情况下)采用以下形式

DATETIME_INPUT_FORMATS = (
    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M:%S.%f',  # '2006-10-25 14:30:59.000200'
    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
    '%Y-%m-%d',              # '2006-10-25'
    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M:%S.%f',  # '10/25/2006 14:30:59.000200'
    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
    '%m/%d/%Y',              # '10/25/2006'
    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M:%S.%f',  # '10/25/06 14:30:59.000200'
    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
    '%m/%d/%y',              # '10/25/06'
)

我尝试添加'%B %d, %Y, %I:%M %p',但我不确定是否%p考虑了a.m.and p.m.(注意字母后面的句点)。这是 Python 关于日期/时间格式的文档的链接。

你们是怎么做到的?您是坚持使用 Django 的默认(丑陋)日期/时间格式,还是在检查之前以某种方式转换时间form.is_valid()(无论是在 JavaScript 还是 Python 中)?


编辑@Thomas Orozco

我写了一个新的表单域,叫做CustomDateTimeField

class CustomDateTimeField(forms.DateTimeField):
    def strptime(self, value, format):
        return datetime.datetime.strptime(value.replace("a.m.", "AM").replace("p.m.", "PM"), "%B %d, %Y, %I:%M %p")

但是,我的表单ModelForm使用fieldsclass Meta. 这就是我的意思:

def order_edit(request, pk):
    order = Order.objects.get(pk=pk)

    if foo:
        include_fields = (
            'fa_date',
            'sa_date',
        )
    else:
        include_fields = (
            'sa_date',
        )

    class OrderDetailForm(forms.ModelForm):
        class Meta:
            model = Order
            fields = include_fields

    if request.method == 'POST':
        form = OrderDetailForm(data=request.POST, instance=order)

whereOrder.sa_dateOrder.fa_dateare both models.DateTimeField。而且我认为我只能使用DateTimeInputfor ModelForm's widgets。那么我将如何告诉表单CustomDateTimeField用于OrderEditForm?我是否需要通过添加额外的论点__init__并手动重新定义类似的字段self.fields['fa_date'] = CustomDateTimeField(...)

4

2 回答 2

2

初步答案

如果您希望您的字段接受特定格式,更简单的解决方案是实现您自己的表单字段,这通常很容易,尤其是在这里,因为 Django 方便地为您提供了一个高效的基类。

事实上,查看django 源代码DateTimeField您可以看到它继承自BaseTemporalField. 因此,您只需要子类BaseTemporalField化并实现该strptime方法,以便它接受您的输入格式。

所述输入格式应该通过input_formats变量传递给您的实例,但如果您愿意编写更多代码,这不是必需的。

您还可以浏览代码DateTimeFieldDateField获得一些灵感。

编辑

您实际上可以覆盖 a 的字段ModelForm:您只需重新定义它们。但是,在您的情况下,您不能使用条件块来执行此操作(您不能if在类定义中包含语句!)。所以你有两个解决方案:

class SAOrderDetailForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = ('sa_date',)
    sa_date = CustomDateTimeField()

class FASAOrderDetailForm(SAOrderDetailForm): #Inheritance matters!
    class Meta:
        model = Order
        fields = ('sa_date','fa_date')
    fa_date = CustomDateTimeField()

if foo:
    FormClass = FASAOrderDetailForm
else:
    FormClass = SAOrderDetailForm

或者,您可以使用表单类的动态创建,但这显然超出了这个问题的范围,所以我将留给您来自 James Bennett 的这篇文章,解释如何做到这一点。

于 2012-05-27T20:44:24.450 回答
1

%p呈现的内容取决于所使用的语言环境。我不确定是否有任何语言环境提供a.m./ p.m.

但是,最简单的方法是为表单字段提供您自己的验证功能。如果这是一次性字段,只需覆盖clean_fieldname(self)表单的方法(其中fieldname是日期时间字段的名称)。请参阅清理特定字段属性

如果您将重复使用此字段,请使用您的验证逻辑创建一个自定义字段,并在需要自定义验证时导入并使用它。您还可以自定义小部件以呈现任何 jquery 选择器。

于 2012-05-27T20:35:17.380 回答