制作Django forms.DateField显示使用本地日期格式 [英] Making Django forms.DateField show use local date format

查看:598
本文介绍了制作Django forms.DateField显示使用本地日期格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



注意事项:




  • 创建一个新的窗口小部件, dd / mm / yyyy格式

  • 创建新的日期字段以将定位日期格式字符串添加到它尝试使用的值列表中



我想象的理想解决方案是自动本地化的日期字段,但这对我并不起作用(strftime似乎不是unicode友好的,但我没有很努力)



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

 从模型导入* 
从django导入表格
导入日期时间
$ b $ class MyDateWidget(forms.TextInput):

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

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

返回超级(MyDateWidget,self).render(name,value,attrs)


class MyDateField(forms.DateField):
$ b $ 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()


解决方案

m不是django / python Jedi,但是...

我不认为你的方法有什么问题。这是一个干净的阅读。

您可能不需要创建自己的小部件,只需在第一个窗体显示中以适当的格式显示日期即可。只需使用格式参数作为 DateInput 小部件,您应该可以。所以在你的MyDateField类中,我只需要做:

pre $ 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)
pre>

您可以使用 formfield_callback (请参阅接受的答案,这个相关的问题),意思是:

  def customize_fields(f):
ifinstance(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)
返回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)
返回日期字段
其他:
返回f.formfield()

class MyModelForm(forms.ModelForm):
formfield_callback = customize_fields
$ b $ class Meta:
model = ...

这样做完全消除了您的 MyDateField 类的需求,但可能会引入 - 如果您希望每一个表单类来调用 customize_fields - 需要ModelForm后代,实现 formfield_callback = customize_fields 作为所有您的新基础表单类。



使用 formfield_callback 机制的问题有两方面:


  1. 它的可读性较差并且依赖于知识ModelForms的内部工作原理。我无法在任何地方找到关于formfield_callback的实际文档...
    如果您需要重新定义ModelForm中的模型字段,请说明使该字段不是对于特定的表单实例,如下所示:

      class MyModelForm(forms.ModelForm):
    formfield_callback = customize_fields
    foo = forms.DateField(required = false)

    class Meta:
    model = Bar

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


我认为您的方法更具可读性。


I'm trying to find an easy way to build forms which show dates in the Australian format (dd/mm/yyyy). This was the only way I could find to do it. It seems like there should be a better solution.

Things to note:

  • Created a new widget which renders date value in dd/mm/yyyy format
  • Created new date field to prepend the locate date format string to the list of values it tries to use

I imagine the ideal solution would be a datefield which automatically localised but that didn't work for me (strftime didn't seem to be unicode friendly but I didn't try very hard)

Am I missing something? Is there a more elegant solution? Is this a robust approach?

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

解决方案

Granted, I'm not a django/python Jedi, but...

I don't think there is anything wrong with your approach. It is a clean read.

You might not need to create your own widget just to render the date in the proper format on the first form display. Just use the format parameter for the DateInput widget and you should be OK. So in your MyDateField class I would just do:

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)

You could use formfield_callback (See the accepted answer for this distantly related question), meaning:

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 = ...

Doing that completely eliminates the need for your MyDateField class, but might introduce - if you want every single form class to call customize_fields - the need for a ModelForm descendent, implementing formfield_callback=customize_fields as the new base for all your form classes.

My problem with using the formfield_callback mechanism is two-fold:

  1. It is less readable and relies in knowledge of the inner workings of ModelForms. I can't find actual documentation on formfield_callback anywhere...

  2. If you ever need to redefine a model field in a ModelForm, say to make the field not required for that particular instance of the form, like so:

       class MyModelForm(forms.ModelForm):
           formfield_callback = customize_fields
           foo = forms.DateField(required=false)
    
           class Meta:
               model = Bar
    

    you are overwriting the form field returned by customize_fields, hence completely losing the customization.

I think your approach is more readable.

这篇关于制作Django forms.DateField显示使用本地日期格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆