我想爲我的表單中的所有字段設置TextInput Widget的類屬性爲一個值,而不必在Meta中列出它們:widgets = {....這可能嗎?如何爲Django ModelForm設置默認控件屬性?
謝謝。在所有的領域
class PrettyWidget(forms.TextInput):
class Media:
css = {
'all': ('pretty.css',)
}
在您的形式使用新的部件:
我想爲我的表單中的所有字段設置TextInput Widget的類屬性爲一個值,而不必在Meta中列出它們:widgets = {....這可能嗎?如何爲Django ModelForm設置默認控件屬性?
謝謝。在所有的領域
class PrettyWidget(forms.TextInput):
class Media:
css = {
'all': ('pretty.css',)
}
在您的形式使用新的部件:
您可以覆蓋的構造,以修改所有的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,如果你使用這很多。
與CSS類創建一個新的widget
class ContactForm(forms.Form):
subject = TextField(widget=PrettyWidget)
這感覺更Djangonic的方式來完成任務,但它並不完全看起來像什麼凱文是我後... – codekoala 2010-09-24 14:43:19
一件事,我已經在過去做的是創造返回領域的lambda函數我經常使用:
from django import forms
fancy = lambda: forms.TextInput(attrs={'class': 'derp'})
class MyForm(forms.Form):
attr1 = fancy()
attr2 = fancy()
attr3 = fancy()
我不記得到底爲什麼我選擇使用一個函數T Ø處理我的情況,但我懷疑它有一些東西需要與創建forms.TextInput對象每個表單字段的不同實例....
這是我現在要做的。有必要創建單獨的forms.Select實例。 – Kevin 2010-09-26 23:59:33
您可以使用下面:
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'}
對於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
你可以用裝飾器重寫init嗎?另外,在attrs.update()之前應該有一個if語句,因爲我想設置一個默認值,而不是覆蓋可能已經存在的值。 – Kevin 2010-09-27 21:44:20
我認爲裝飾器是用於可調用的,覆蓋構造函數應該通過正常的繼承機制來完成。在Django中,有一些函數返回類並不罕見,這些函數通常被稱爲「工廠」。更新爲「if」條件(未經測試)。 – 2010-09-28 15:02:40