如何修改Django中某种类型的所有内置表单字段的默认小部件?

时间:2009-03-20 00:03:40

标签: django django-forms widget django-widget

这是对How do you change the default widget for all Django date fields in a ModelForm?的跟进。

假设您有大量模型(例如A-ZZZ)随着您无法控制的其他开发人员的输入而增长,并且您想要更改所有日期字段的输入方式(即使用jQueryUI) )。确保使用新窗口小部件填写所有日期字段的最佳方法是什么?

引用问题的一个建议是:

def make_custom_datefield(f):
   if isinstance(f, models.DateField):
       # return form field with your custom widget here...
   else:
       return f.formfield()

class SomeForm(forms.ModelForm): 
   formfield_callback = make_custom_datefield

   class Meta:
       # normal modelform stuff here...

但是,如果您没有明确的ModelForm,可以这样做吗,但url模式直接来自模型吗?即你的url配置是likeo:

url(r'^A/?$', 'list_detail.object_list', SomeModelA)

其中SomeModelA是由Django在后台变成ModelForm的模型(不是表单)。

目前在我的系统中,每个模型都没有表格。明确创建表单的唯一方法是添加先前解决方案中建议的formfield_callback,但这违反了DRY原则,并且容易出错且需要大量人力。

我已经考虑过(正如在最后一个帖子中所建议的)创建我自己的字段,该字段具有特殊的小部件并使用它而不是内置的。它不是那么劳动密集型,但它可能会出错(但没有好的grep无法修复)。

赞赏建议和想法。

1 个答案:

答案 0 :(得分:7)

听起来你想要在整个项目范围内这样做(例如:在某些情况下你不会尝试这样做,但是在你正在运行的应用程序的所有情况下)。

一种可能性是替换DateField类本身的widget属性。您需要在某个中心位置执行此操作...保证由django应用程序的每个运行实例加载。中间件可以帮助解决这个问题。否则,只需将其放入应用的__init__文件中即可。

您要做的是为forms.DateField类本身重新分配widget属性。当创建新的DateField时,Django会检查代码是否指定了字段属性定义中的任何特定小部件。如果不是,它使用DateField的默认值。我假设,如果您的方案中的用户确实定义了特定的小部件,那么即使您对全局API进行了更改,也要保证这一点。

尝试将此默认设置为其他窗口小部件的示例...在本例中为HiddenInput:

from django import forms
forms.DateField.widget = forms.HiddenInput

class Foo(forms.Form):
    a = forms.DateField()

f = Foo()
print f.fields['a'].widget
# results in <django.forms.widgets.HiddenInput object at 0x16bd910>