使 Django forms.DateField 显示使用本地日期格式
我正在尝试找到一种简单的方法来构建以澳大利亚格式(dd/mm/yyyy)显示日期的表单。这是我能找到的唯一方法。看来应该有更好的解决方案。
需要注意的事项:
- 创建了一个新的小部件,以 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()
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当然,我不是 django/python Jedi,但是......
我不认为你的方法有什么问题。这是一本干净的读物。
您可能不需要创建自己的小部件,只是为了在第一个表单显示上以正确的格式呈现日期。只需使用
DateInput
小部件的format
参数就可以了。因此,在您的 MyDateField 类中,我会这样做:您可以使用
formfield_callback
(请参阅 接受了这个遥远相关问题的答案),意思是:这样做完全消除了对
MyDateField< 的需要/code> 类,但可能会引入 - 如果您希望每个表单类都调用
customize_fields
- 需要 ModelForm 后代,实现formfield_callback=customize_fields
作为新的基础您所有的表格课程。我使用
formfield_callback
机制的问题有两个:它的可读性较差,并且依赖于对 ModelForms 内部工作原理的了解。我在任何地方都找不到有关 formfield_callback 的实际文档...
如果您需要在 ModelForm 中重新定义模型字段,比如说使该字段对于表单的特定实例不需要,如下所示:
您将覆盖customize_fields返回的表单字段,因此完全失去了自定义功能。
我认为你的方法更具可读性。
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 theDateInput
widget and you should be OK. So in your MyDateField class I would just do:You could use
formfield_callback
(See the accepted answer for this distantly related question), meaning:Doing that completely eliminates the need for your
MyDateField
class, but might introduce - if you want every single form class to callcustomize_fields
- the need for a ModelForm descendent, implementingformfield_callback=customize_fields
as the new base for all your form classes.My problem with using the
formfield_callback
mechanism is two-fold:It is less readable and relies in knowledge of the inner workings of ModelForms. I can't find actual documentation on formfield_callback anywhere...
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:
you are overwriting the form field returned by customize_fields, hence completely losing the customization.
I think your approach is more readable.
我以前使用过这种简单的方法:只需在表单的 init 中设置 DateField.widget 的“format”属性:
I've used this simple approach before: just set the 'format' attribute of the DateField.widget in the init of the Form:
所有自定义小部件的内容都可以被绕过。
以下是 django/forms/widgets.py 的摘录:
您会注意到小部件的格式是使用 format 模块设置的。根据区域设置选择格式模块。如果您从美国浏览,Django 将默认选择 django.conf.formats.locale.en.formats.py。在这里您将找到默认格式:
正如您在第一个代码块中看到的,Django 选择其中的第一个。更改格式的彻底方法是创建您自己的格式模块,覆盖 Django 对于相关区域设置的默认设置。为此,请查看 FORMAT_MODULE_PATH。如果您想做的只是覆盖默认日期格式,我建议您节省一些时间和猴子补丁。我将其添加到我的设置文件中,一切似乎都以我喜欢的默认格式运行得很好:
All of the custom widget stuff can be bypassed.
Here's an excerpt from
django/forms/widgets.py
:You'll notice that the format of the widget is set using the format module. The format module is selected depending on the locale. If you're browsing from the US, Django will, by default, select
django.conf.formats.locale.en.formats.py
. Here you will find the default format:As you can see in the first code block, Django selects the first of these. The thorough approach to changing the format is to create your own format module, overriding Django's default for the locale in question. For that, look into FORMAT_MODULE_PATH. If all you're trying to do is override the default date format, I say save yourself some time and monkey patch. I added this to my settings file and everything appears to be working splendidly with my preferred default format:
在我的表格中,我使用:
In my form I'me using: