分享

python测试开发django-109.ModelForm模型表单的使用

 上海悠悠 2021-07-15

前言

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将模型的字段类型查询定义为表单字段类型,默认情况模型字段自动转表单字段类型

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多