Django之ModelForm
什么是ModelForm
顾名思义,ModelForm就是数据模型和表单的结合体。单纯的Form表单只是对数据进行验证、在模板生成HTML。但这个ModelForm也包含了以上Form的功能,这是一个基于数据模型的一个组件,结合数据库使用的。
例一、利用ModelForm添加数据
有以下数据库
from django.db import models
# Create your models here.
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
def __str__(self):
return self.username
class Host(models.Model):
hostname = models.CharField(max_length=32, verbose_name='主机名') # verbose_name用于在模板中生成label标签
ip = models.GenericIPAddressField(protocol='ipv4')
port = models.IntegerField()
user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE, default=1)
dp = models.ManyToManyField(to='Department')
class Department(models.Model):
title = models.CharField(max_length=32)
def __str__(self):
return self.title
ModelForm的创建
from django.forms import widgets
from app01 import models
# 创建一个ModelForm类
class HostModelForm(ModelForm):
class Meta:
model = models.Host # 定义了引用的数据模型
fields = '__all__' # 定义引用数据模型的哪些字段,也可以为列表,如['username','ip']
# 定义标签名称,也可在数据模型中使用参数verbose_name定义
labels = {
'dp': '部门',
'ip': 'IP',
'port': '端口',
'user': '用户名'
}
error_messages = { # 定义错误信息
'hostname': {'required': '用户名不能为空'},
'ip': {'required': 'ip不能为空'},
'port': {'required': '端口不能为空'},
'dp': {'required': '必须要选部门'},
}
表单中的渲染
{# 循环ModelForm,可获取每个field,相当于form.username、form.ip#}
{% for field in form %}
{{ field.label }}:{{ field }}{{ field.errors.0 }}
{% endfor %}
View视图函数
def add_host(request):
if request.method == 'GET':
form = forms.HostModelForm() # 用于渲染网页
else:
form = forms.HostModelForm(data = request.POST) # 校验数据
if form.is_valid():
form.save() # 保存到数据库
return redirect('/host/')
return render(request, 'add_host.html', {'form': form})
利用ModelForm编辑数据
模板
{# 循环ModelForm,可获取每个field,相当于form.username、form.ip#}
{% for field in form %}
{{ field.label }}:{{ field }}{{ field.errors.0 }}
{% endfor %}
视图函数
def edit_host(request, nid):
host_obj = models.Host.objects.filter(id=nid).first()
if request.method == 'GET':
form = forms.HostModelForm(instance=host_obj) # 把对象传给ModelForm,以方便于网页渲染
else:
form = forms.HostModelForm(data=request.POST, instance=host_obj) # 对instance实例用data更新数据
if form.is_valid():
form.save()
return redirect('/host/')
return render(request, 'edit_host.html', {'form': form})
要点总结
form = forms.HostModelForm() # 用于渲染空的模板 form = forms.HostModelForm(instance = obj) # 用于渲染一个带有obj数据的模板 form = forms.HostModelForm(data=request.POST) # 准备校验的数据 form = forms.HostModelForm(data=request.POSt, instance = obj) # 对对象obj更新数据 form.save() # 保存数据 form.is_valid() # 校验数据
内容补充
插件
这个插件的使用和Form差不多,但注意需要首先给widgets模块给个别名,因为这和参数名重复 示例如下:from django.forms import fields
from django.forms import Form, ModelForm
from django.forms import widgets as mfwidgets # 起一个别命
from app01 import models
class HostModelForm(ModelForm):
class Meta:
model = models.Host # 定义了引用的数据模型
fields = '__all__' # 定义引用数据模型的哪些字段,也可以为列表,如['username','ip']
# 定义标签名称,也可在数据模型中使用参数verbose_name定义
labels = {
'dp': '部门',
'ip': 'IP',
'port': '端口',
'user': '用户名'
}
error_messages = { # 定义错误类型
'hostname': {'required': '用户名不能为空'},
'ip': {'required': 'ip不能为空'},
'port': {'required': '端口不能为空'},
'dp': {'required': '必须要选部门'},
}
widgets = { # 和form使用方法类似,这里演示了对hostname字段html的生成。
'hostname': mfwidgets.Textarea(attrs={'class': 'c1'})
}
钩子函数
和Form一样的添加定制form字段
ModelForm是依赖于数据模型,而现在需要使用的是数据模型以外的字段,可在class Meta类上面定义,如下:class HostModelForm(ModelForm):
test = fields.CharField() # 新增字段
class Meta:
model = models.Host # 定义了引用的数据模型
fields = '__all__' # 定义引用数据模型的哪些字段,也可以为列表,如['username','ip']
# 定义标签名称,也可在数据模型中使用参数verbose_name定义
labels = {
'dp': '部门',
'ip': 'IP',
'port': '端口',
'user': '用户名'
}
error_messages = { # 定义错误类型
'hostname': {'required': '用户名不能为空'},
'ip': {'required': 'ip不能为空'},
'port': {'required': '端口不能为空'},
'dp': {'required': '必须要选部门'},
}
widgets = {
'hostname': mfwidgets.Textarea(attrs={'class': 'c1'})
}
但如果定义的字段名与数据模型重复,会把数据模型的覆盖
浙公网安备 33010602011771号