ModuleForm依赖models模块,如果项目小可以使用,项目大或以后会进行拆分不建议使用。
如果用Form的话我们需要对字段进行重新设定,如下。
from django.forms import Form from django.forms import ModelForm from django.forms import fields from django.forms import widgets as fwidgets class LoginForm(Form): username=fields.CharField( label='用户名:', required=True, error_messages={ 'required':'用户名不能为空' } ) password=fields.CharField( label='密 码:', required=True, error_messages={ 'required':'密码不能为空' }, widget=fwidgets.PasswordInput() )
ModleForm不需要对字段进行重设,只需要实例化对应的表
from app01 import models class HostModelForm(ModelForm): class Meta: model=models.Host#实例化表 #fields=['hostname','ip']需要的字段 fields="__all__"#需要所有字段 labels={ 'ip':'IP', 'port':'端口' }#别名 error_messages={ 'hostname':{ 'required':'主机名不能为空!' }, 'ip':{ 'required':'ip不能为空' }, 'port': { 'required': '端口不能为空' },#错误信息 }
当使用url首次请求页面的时候即get请求,视图函数中一样。
#form组件 if request.method=="GET": form = forms.LoginForm() return render(request,"login.html",{'form':form}) #modelForm if request.method=="GET": form = forms.HostModelForm() return render(request,'add_host.html',{'form':form})
html模板中渲染方式相同
#form组件 <form method="post" novalidate> {% csrf_token %} <p>{{ form.username.label }} {{ form.username }} {{ form.username.errors.0 }}</p> <p>{{ form.password.label }} {{ form.password }} {{ form.password.errors.0 }}</p> <input type="submit" value="提交"> </form> #modelForm <form method="post" novalidate > {% csrf_token %} <p>{{ form.hostname.label }}{{ form.hostname }}{{ form.hostname.errors.0 }}</p> <p>{{ form.ip.label }}{{ form.ip }}{{ form.ip.errors.0 }}</p> <p>{{ form.port.label }}{{ form.port }}{{ form.port.errors.0 }}</p> <p>{{ form.user.label }}{{ form.user }}{{ form.user.errors.0 }}</p> <p>{{ form.dp.label }}{{ form.dp }}{{ form.dp.errors.0 }}</p> <input type="submit" value="提交"> </form> #也可使用for循环 {% for field in form %} <p>{{ field.label }}{{ field }}{{ field.errors.0 }}</p> {% endfor %}
modelform可以将一对多,多对多表关系的字段自动对应显示。
添加记录
def add_host(request): if request.method=="GET": form = forms.HostModelForm() return render(request,'add_host.html',{'form':form}) else: form=forms.HostModelForm(data=request.POST) if form.is_valid(): print(form.cleaned_data) #自动保存所有数据,包括多对多 obj=form.save() return redirect('/host/') return render(request,'add_host.html',{'form':form})
编辑记录
def edit_host(request,nid): obj=models.Host.objects.filter(id=nid).first() if not obj: return HttpResponse('数据不存在') if request.method=='GET': form=forms.HostModelForm(instance=obj) return render(request,'edit_host.html',{'form':form}) else: #提交的数据需要给obj实例做更新 form=forms.HostModelForm(data=request.POST,instance=obj) if form.is_valid(): form.save() return redirect('/host/') return render(request,'edit_host.html',{'form':form})
相对于form,modelform保存数据更便捷,一对多,多对多的关系,会自动保存
modelform还支持,钩子,自定义字段
from app01 import models class HostModelForm(ModelForm): # xxx = fields.CharField()#自定义字段 class Meta: model=models.Host #fields=['hostname','ip'] fields="__all__" labels={ 'ip':'IP', 'port':'端口' } error_messages={ 'hostname':{ 'required':'主机名不能为空!' }, 'ip':{ 'required':'ip不能为空' }, 'port': { 'required': '端口不能为空' }, } widgets={ 'hostname':fwidgets.Textarea(attrs={'class':'c1'}) } def clean_hostname(self): from django.core.exceptions import ValidationError if self.cleaned_data['hostname'] =='111': raise ValidationError('主机名存在') return self.cleaned_data['hostname']