这是对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无法修复)。
赞赏建议和想法。
答案 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>