我想将TextInput Widget的class属性设置为我的表单中使用它的所有字段的一个值,而不必在Meta中列出它们:widgets = {....这可能吗?< / p>
感谢。
答案 0 :(得分:14)
您可以覆盖构造函数以修改所有TextInput小部件:
from django import forms
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
if field.widget.__class__ == forms.widgets.TextInput:
if 'class' in field.widget.attrs:
field.widget.attrs['class'] += ' my-class'
else:
field.widget.attrs.update({'class':'my-class'})
class Meta:
model = MyModel
你可以用装饰器覆盖init吗?另外,在attrs.update()之前应该有一个if语句因为我想设置一个默认值而不是覆盖可能已存在的内容。 - 凯文
未经测试,但我猜你可以继承MyForm,如果你经常使用它。
答案 1 :(得分:3)
使用CSS类创建一个新小部件:
class PrettyWidget(forms.TextInput):
class Media:
css = {
'all': ('pretty.css',)
}
在您的表单中,在所有字段中使用新窗口小部件:
class ContactForm(forms.Form):
subject = TextField(widget=PrettyWidget)
答案 2 :(得分:3)
我过去做过的一件事是创建一个lambda函数,它返回我经常使用的字段:
from django import forms
fancy = lambda: forms.TextInput(attrs={'class': 'derp'})
class MyForm(forms.Form):
attr1 = fancy()
attr2 = fancy()
attr3 = fancy()
我不记得为什么我选择使用函数来处理我的情况,但我怀疑它与为每个表单字段创建forms.TextInput对象的单独实例有关....
答案 3 :(得分:1)
您可以使用以下内容:
def set_attrs_for_fields(fields, default_attrs):
for field_name in fields:
field = fields[field_name]
try:
default_widget_attr = default_attrs[field.widget.__class__]
field.widget.attrs = default_widget_attr
except KeyError:
pass
class DefaultAttrForm(forms.Form):
def __init__(self, *args, **kwargs):
super(DefaultAttrForm, self).__init__(*args, **kwargs)
set_attrs_for_fields(self.fields, self.get_default_attrs())
def get_default_attrs(self):
'''
Child class should overwrite this method and return dict with example format
{forms.TextInput: {'class': 'my_value'}}
where keys, are widget classes for which default attrs will be set.
'''
raise NotImplementedError()
class DefaultAttrModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super(DefaultAttrModelForm, self).__init__(*args, **kwargs)
set_attrs_for_fields(self.fields, self.get_default_attrs())
def get_default_attrs(self):
'''
Child class should overwrite this method and return dict with example format
{forms.TextInput: {'class': 'my_value'}}
where keys, are widget classes for which default attrs will be set.
'''
raise NotImplementedError()
现在,每次要为某个窗口小部件使用默认attrs时,只需要创建继承自DefaultAttrForm或DefaultAttrModelForm并覆盖方法get_default_attrs
的类。正常Django表单的示例:
class MyForm(DefaultAttrForm):
my_field1 = forms.CharField(widget=forms.TextInput())
my_field2 = forms.CharField(widget=forms.PasswordInput(attrs={'my_non_default': 'Non default'}))
def get_default_attrs(self):
# all fields with widget TextInput will have
# default attrs set to {'class': 'my_value'}
return {forms.TextInput: {'class': 'my_value'},
}
In [1]: form = MyForm()
In [2]: form.fields['my_field1'].widget.attrs
Out[2]: {'class': 'my_value'}
In [3]: form.fields['my_field2'].widget.attrs
Out[3]: {'my_non_default': 'Non default'}
对于模型表单,请使用以下命令:
class MyModelForm(DefaultAttrModelForm):
class Meta:
model = my_model
def get_default_attrs(self):
# all fields with widget TextInput will have
# default attrs set to {'class': 'my_value'}
return {forms.TextInput: {'class': 'my_value'},
}
In [1]: form = MyModelForm()
In [2]: form.fields['my_field1'].widget.attrs
Out[2]: {'class': 'my_value'}
In [3]: form.fields['my_field2'].widget.attrs
Out[3]: {'my_non_default': 'Non default'}
答案 4 :(得分:1)
对于ModelForm,我们可以使用它。
from django import forms
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
# change a widget attribute:
self.fields['user_permissions'].widget.attrs["size"] = 5
self.fields['user_permissions'].widget.attrs["class"] = 'form-control required'
class Meta:
model = User