咱們在使用django定義好一個model後,可能須要添加或者修改model數據,此時能夠藉助於django提供的forms表單組件.django
forms表單和model結合使用時,必須在Meta類中指定關聯的model和須要展現的字段(field)ide
django會自動根據每一個字段的類型來生成適合的forms字段ui
若有一個外鍵字段,django會自動把他轉化成其關聯的對象而不是簡單的展現其關聯的id.spa
一個簡單的model關聯的forms表單定義,如FlowStageForm1.orm
class FlowStageForm1(forms.ModelForm):
class Meta:
model = WorkFlowStage
fields = '__all__'
exclude = ['work_type'] # 排除該字段
對象
有時候forms默認的渲染可能不知足咱們的需求,這時就須要經過手動來定義部分字段來知足咱們的需求,沒有手動定義的字段django會默認幫咱們渲染.文檔
可是有時候只是想簡單的修改個小地方,如在全部的字段上添加一個默認的類,難道要把全部的字段都定義一遍嗎,很蛋疼.get
研究了一下官方文檔,發現仍是有方法的it
能夠在__init__初始化時直接循環全部的字段,給他們添加一些屬性,而不用從新定義他們.鉤子
若是一個表有10個字段,有九個字段有共同屬性,而有一個須要單獨定製widget,這時候只需在forms中單獨定義完,在__init__初始化添加通用屬性的時候排除他便可,見紅色代碼處.
再若是咱們想改變字段widget但又想保留django提供的一些功能,若是一個字段是外鍵,當咱們自動在forms中定義事後,就不能使用django默認的功能,須要手動寫代碼去關聯其對象,這時候能夠在Meta中使用widgets來單獨定義該字段的widget同時保留了django提供的一些特性,這樣就完美了.
實例見FlowStageForm
# work_flow是WorkFlowStage的外鍵
class FlowStageForm(forms.ModelForm):
handler_id = forms.IntegerField(label="參與人ID", required=False,
widget=forms.HiddenInput())
hook_method_name = forms.CharField(label="鉤子程序方法名", required=False,
widget=forms.TextInput(attrs={'class': 'form-control'}))
class Meta:
model = WorkFlowStage
fields = '__all__'
exclude = ['work_type'] # 排除該字段
widgets = {
'work_flow': forms.Select(attrs={'class': 'form-control disabled', 'required': 'required'}), #work_flow是一個外鍵
'handler_id_display': forms.TextInput(attrs={'class': 'form-control disabled', 'required': 'required'})
}
def __init__(self, **kwargs):
super(FlowStageForm, self).__init__(**kwargs)
#保存用戶有自定義過的fields不對其進行更改.
declared_fields = []
if self.declared_fields: # 自定義過的field
declared_fields += list(self.declared_fields)
if self.Meta.widgets:
declared_fields += list(self.Meta.widgets) # 修改過widgets的部件.
attrs = {'class': 'form-control', 'required': 'required'}
for field in self.fields:
if field not in declared_fields: # 排除掉有過自定義的field
self.fields[field].widget.attrs.update(attrs)