一. 創(chuàng)建一個(gè)ModelForm
1.1 使用之前需要導(dǎo)入對(duì)應(yīng)app中的models和Django提交的ModelForm類
from django.forms import ModelForm
from app01.models import Host
from django.forms import widgets #插件,接下來會(huì)用到
from django.core.exceptions import ValidationError
1.2 創(chuàng)建一個(gè)類径密,并繼承ModelForm
class HostModelForm(ModelForm): #新建1個(gè)類午阵,繼承ModelForm
class Meta: #在內(nèi)部定義一個(gè)Meta類,注意這個(gè)類名是固定不變的
model = Host #對(duì)應(yīng)models.py中哪個(gè)類(哪個(gè)表)
fields = '__all__' #表示使用models.Host類中所有字段
# fields = ('hostname','ip','port','dep') #也可以這樣選擇指定字段
ModelForm常用的class Meta配置
class Meta:
model = models.UserInfo #結(jié)尾不用加逗號(hào)
fields = '__all__'
# fields = ['username','email']
# exclude = ['username'] # 除了 XX字段享扔,其他都使用
labels = { # label 名稱
'username': '用戶名',
'email': '郵箱',
}
help_texts = { # 幫助信息
'username': '...'
}
widgets = {
'username': Fwidgets.Textarea(attrs={'class': 'c1'})
}
error_messages = { # 自定義錯(cuò)誤
'__all__':{
},
'email': {
'required': '郵箱不能為空',
'invalid': '郵箱格式錯(cuò)誤..',
}
}
field_classes = { #字段類型底桂,可以強(qiáng)制修改成其他類型
# 'email': Ffields.URLField
}
# localized_fields=('ctime',)
二. ModelForm生成Html和數(shù)據(jù)驗(yàn)證
2.1 生成空表單
forms = HostModelForm() # 生成空的表單
2.2 在表單中顯示初始數(shù)據(jù)
hostobj =models.Host.objects.get(id=1)
forms = HostModelForm(instance = hostobj) # instance 對(duì)應(yīng)模型實(shí)例
2.3 驗(yàn)證表單數(shù)據(jù)并保存
forms = HostModelForm(request.POST)
if forms.is_valid(): # 驗(yàn)證成功則保存modelsform
forms.save() # 這一步會(huì)直接將數(shù)據(jù)保存至數(shù)據(jù)庫
注意:此時(shí),forms.save()不僅保存當(dāng)前對(duì)象實(shí)例伪很,還保存實(shí)例對(duì)應(yīng)跨表關(guān)系(外鍵戚啥、多對(duì)多等)
三. 前端頁面展示form表
在模版中展示指定字段
<form method="post" novalidate>
{% csrf_token %}
<p>{{ forms.hostname.label }}: {{ forms.hostname }}{{ forms.hostname.errors.0 }}</p>
<p>{{ forms.ip.label }}: {{ forms.ip }}{{ forms.ip.errors.0 }}</p>
<p>{{ forms.port.label }}: {{ forms.port }}{{ forms.port.errors.0 }}</p>
<input type="submit" value="提交">
</form>
如果嫌上面這種方法麻煩,還可以在模版中循環(huán)forms實(shí)例锉试,以列出每個(gè)字段
<form method="post" novalidate>
{% csrf_token %}
{% for form in forms %}
<p>{{ form.label }}: {{ form }}{{ form.errors.0 }}</p>
{% endfor %}
<input type="submit" value="提交">
</form>
四. 示例
4.1 在app中創(chuàng)建一個(gè)forms.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author : Cai Guangyin
from django.forms import ModelForm
from app01.models import Host
from django.forms import widgets
from django.core.exceptions import ValidationError
class HostModelForm(ModelForm): #新建1個(gè)類猫十,繼承ModelForm
class Meta:
model = Host #對(duì)應(yīng)models.py中哪個(gè)類(哪個(gè)表)
fields = '__all__' #表示使用models.Host類中所有字段
# fields = ('hostname','ip','port','dep') #也可以這樣選擇指定字段
error_messages = { #自定義錯(cuò)誤提示信息
'hostname':{
'required':'用戶名不能為空'
},
'ip':{
'required':'IP不能為空',
'invalid':'IP地址格式錯(cuò)誤'
},
'port':{
'required':'端口不能為空'
},
'dep': {
'required': '部門不能為空'
},
'userinfo': {
'required': '所屬用戶不能為空'
},
}
labels = { #自定義label標(biāo)簽顯示的內(nèi)容
'hostname':'主機(jī)名',
'ip':'IP',
'port':'端口',
'dep':'部門',
'userinfo':'所屬用戶'
}
widgets = { # 自定義插件,注意必須加s,因?yàn)槭菑?fù)數(shù)呆盖,寫widget不起作用
'hostname': widgets.TextInput(attrs={'class':'form-control'}),
'ip': widgets.TextInput(attrs={'class':'form-control'}),
'port': widgets.TextInput(attrs={'class':'form-control'}),
'dep': widgets.Select(attrs={'class':'form-control'}),
'userinfo': widgets.SelectMultiple(attrs={'class':'form-control'}),
}
def clean_port(self): #也可以自定義鉤子函數(shù)對(duì)字段進(jìn)行驗(yàn)證
value = self.cleaned_data['port']
if int(value) > 65535:
raise ValidationError('端口號(hào)不能大于65535')
return value
4.2 views.py
from django.shortcuts import render
from .models import *
from .forms import HostModelForm
# Create your views here.
def index(request):
forms = HostModelForm() #創(chuàng)建空表單
if request.method == 'POST':
forms = HostModelForm(request.POST) #提交數(shù)據(jù)
if forms.is_valid(): #驗(yàn)證數(shù)據(jù)
forms.save()
return render(request,'index.html',locals())
def edit_host(request):
host_obj = Host.objects.filter(pk=1).first()
forms = HostModelForm(instance=host_obj) #編輯時(shí)顯示默認(rèn)數(shù)據(jù)
if request.method == 'POST':
# host_obj = Host.objects.filter(pk=1).first()
# forms = HostModelForm(request.POST) #向modelform中傳遞數(shù)據(jù)
forms = HostModelForm(data=request.POST,instance=host_obj) #編輯保存時(shí)拖云,需要將data和instance都傳入
if forms.is_valid():
forms.save()
return render(request,'edithost.html',locals())
注意:在修改表單(表單中有初始值),提交驗(yàn)證時(shí)应又,需要傳入data和instance兩個(gè)參數(shù)宙项,如:
forms = HostModelForm(data=request.POST,instance=host_obj)
4.3 模版文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" novalidate>
{% csrf_token %}
{% for form in forms %}
<p>{{ form.label }}: {{ form }}{{ form.errors.0 }}</p>
{% endfor %}
<input type="submit" value="提交">
</form>
</body>
</html>