python测试开发django-109.ModelForm模型表单的使用
前言
django的表单有2种:forms.Form 和 forms.ModelForm。ModelForm顾名思义是将模型和表单结合起来,这个功能是非常强大的!
Model模型
Model模型设计如下
from django.db import models
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
# Create your models here.
class Detail(models.Model):
user = models.CharField(max_length=30, blank=True, null=True)
age = models.IntegerField(blank=True, null=True)
email = models.EmailField(blank=True, null=True)
city = models.CharField(max_length=30, blank=True, null=True)
GENDER_CHOICES = (
('男', '男'),
('女', '女'),
)
gender = models.CharField(
max_length=30,
choices=GENDER_CHOICES
)
fancy = models.CharField(max_length=30, blank=True, null=True)
comment = models.TextField()
birth = models.DateTimeField()
ModelForm模型表单
在视图中,定义一个类DetailModelForm,这个类要继承forms.ModelForm,在这个类中再写一个原类Meta
from django.forms import models as form_model
from django.forms import widgets
from .models import Detail
from django.views import View
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
class DetailModelForm(forms.ModelForm):
"""模型表单"""
class Meta:
model = Detail # 对应的Model中的类
# fields = "__all__" # 字段,如果是__all__,就是表示列出所有的字段
fields = ["user", "age", "gender", "email", "city", "birth", "comment", "fancy"]
exclude = None # 排除的字段
help_texts = None # 帮助提示信息
error_messages = {
'user': {'required': 'user不能为空',
'min_length': 'user不能少于3个字符',
'max_length': 'user不能超过12个字符'},
'age': {'min_value': '不能小于0', },
'gender': {'invalid': '输入不合法'},
'email': {'invalid': '输入不合法'},
'city': {'invalid': '输入不合法'},
}
# widgets 用法, 比如把输入用户名的input框给为Textarea
widgets = {
"user": widgets.TextInput(attrs={"class": "xx"}),
"age": widgets.NumberInput,
"gender": widgets.RadioSelect(choices=[
(1, '男'),
(2, '女')
]),
"email": widgets.EmailInput,
"city": widgets.Select(choices=[
("北京", "北京"),
("上海", "上海"),
("深圳", "深圳"),
("杭州", "杭州"),
]),
"birth": widgets.DateInput(attrs={'type': 'date', 'value': '2021-01-01'}),
"comment": widgets.Textarea,
# 多选checkbox
"fancy": widgets.CheckboxSelectMultiple(
choices=((1, 'Python'), (2, 'Selenium'), (3, "Appium"))
),
}
# labels,自定义在前端显示的名字
labels = {
"user": "姓名",
"age": "年龄",
"gender": "性别",
"email": "邮箱",
"city": "城市",
"birth": "出生年月",
"comment": "评论",
"fancy": "爱好"
}
在视图中可以直接通过form_obj.save()保存数据,非常方便。
from django.views import View
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
class DetailModelView(View):
def get(self, request):
form_obj = DetailModelForm()
return render(request, "detail.html", locals())
def post(self, request):
form_obj = DetailModelForm(request.POST)
if form_obj.is_valid():
# data = form_obj.cleaned_data()
form_obj.save()
msg = "保存成功"
return render(request, "detail.html", locals())
else:
# 全局钩子自定义错误提示获取
print(form_obj.errors.get('__all__')[0])
error_msg = form_obj.errors.get('__all__')[0]
return render(request, "detail.html", locals())
模板与显示效果
detail.html模板内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>详情页面</title>
<style>
ul li{
list-style: none;
}
</style>
</head>
<body>
<form action="" method="POST" id="detail-form" >
{% csrf_token %}
{% for field in form_obj %}
{% if field.label == "性别" %}
{{ field.label_tag }}
{{ field.1 }} {{ field.2 }}
{% elif field.label == "爱好" %}
{{ field.label_tag }}
{% for f in field %}
{{ f }}
{% endfor %}
{% else %}
<p>
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</p>
{% endif %}
{% endfor %}
<p>
{% if msg %}
{{ msg }}
{% endif %}
</p>
<p>
<input type="submit" value="提交" >
</p>
</form>
</body>
</html>
页面显示效果
Meta中属性
属性 | 说明 |
---|---|
model | 必须项,对应的Model中的类 |
fields | 字段,如果是__all__,就是表示列出所有的字段 |
exclude | 排除的字段 |
labels | 提示信息 |
help_texts | 帮助提示信息 |
widgets | 自定义插件 |
error_messages | 自定义错误信息 |
field_classes | 将模型的字段类型查询定义为表单字段类型,默认情况模型字段自动转表单字段类型 |