Django ModelForm表单验证
ModelForm
在使用Model和Form时,都需要对字段进行定义并指定类型,通过ModelForm则可以省去From中字段的定义
应用场景:定制model admin 的时候可以使用。适用于小业务架构。
ModelForm
a. class Meta:
model, # 对应Model的
fields=None, # 字段
exclude=None, # 排除字段
labels=None, # 提示信息
help_texts=None, # 帮助提示信息
widgets=None, # 自定义插件
error_messages=None, # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
field_classes=None # 自定义字段类 (也可以自定义字段)
localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
如:
数据库中
2016-12-27 04:10:57
setting中的配置
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True
则显示:
2016-12-27 12:10:57
b. 验证执行过程
is_valid -> full_clean -> 钩子 -> 整体错误 c. 字典字段验证
def clean_字段名(self):
# 可以抛出异常
# from django.core.exceptions import ValidationError
return "新值"
d. 用于验证
model_form_obj = XXOOModelForm()
model_form_obj.is_valid()
model_form_obj.errors.as_json()
model_form_obj.clean()
model_form_obj.cleaned_data
e. 用于创建
model_form_obj = XXOOModelForm(request.POST)
#### 页面显示,并提交 #####
# 默认保存多对多
obj = form.save(commit=True)
# 不做任何操作,内部定义 save_m2m(用于保存多对多)
obj = form.save(commit=False)
obj.save() # 保存单表信息
obj.save_m2m() # 保存关联多对多信息 f. 用于更新和初始化
obj = model.tb.objects.get(id=1)
model_form_obj = XXOOModelForm(request.POST,instance=obj)
... PS: 单纯初始化
model_form_obj = XXOOModelForm(initial={...})
views.py
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo
fields = '__all__' # 请求处理
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
models.py
class UserType(models.Model):
caption = models.CharField(max_length=32) class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to=UserType, to_field='id', on_delete=models.SET_NULL,null=True)
注:verbose_name 为django admin管理数据 的时候显示 的字段。在模板中渲染时,调用modelForm对象实例也可以显示对应的中文
{{ verify_obj.as_p }}
{{ verify_obj.as_ul }}
{{ verify_obj.as_table }}
modelForm.html
<form action="/modelformtest/" method="post">
{% csrf_token %}
{{ verify_obj.as_p }}
<input type="submit" value="提交">
</form>
访问效果

-------------------------------------------------------------------------------------------------------------
只展示指定列 fields =
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo
# fields = '__all__'
fields = ['username', ]

排除指定列 :exclude = ['xxx',...]
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo
# fields = '__all__'
# fields = ['username', ]
exclude = ['username']

labels 效果等于models.py里面定义数据表字段时的 verbose_name='xxx'
为对输入字段自定义提示语
views.py
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
labels = { # 生成html标签的对应input标签前面的提示
'username': 'lables 用户名',
'email': '邮箱',
'user_type': '用户类型'
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
modelForm.html
<form action="/modelformtest/" method="post">
{% csrf_token %}
{{ verify_obj.as_p }}
<input type="submit" value="提交">
</form>

------------------------------------------------------------------------
help_texts=None, # 帮助提示信息
views.py
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
help_texts = { # 提示信息
'username': '用户名哦',
'email': '邮箱啊'
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
html
{{ verify_obj.as_p }}

--------------------------------------------------------------------
widgets=None, # 自定义标签类型插件
wiews.py
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
widgets = {
'username': forms_widgets.Textarea(attrs={'class': 'test-class'})
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
html
<form action="/modelformtest/" method="post">
{% csrf_token %}
{{ verify_obj.as_p }}
<input type="submit" value="提交">
</form>

--------------------------------------------------------------------------------------------
error_messages = {'字段名': {'错误类型': '错误提示', ... }}
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
error_messages = {
'email': {
'required': '必填',
'invalid': '邮箱格式错误'
},
'username': {
'max_length': '太长了',
'min_length': '太短了',
}
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj}) def post(self, request):
# 获取所有数据
# 每条数据请求的验证
# 成功显示正确信息
# 失败,给出错误提示
# 验证时将request.POST 传递给验证类,实例化验证对象
# verify_obj = MyFm(request.POST)
verify_obj = UserInfoModelForm(request.POST) verify_result = verify_obj.is_valid() # 验证是否通过,返回True/False
if not verify_result:
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
# 整体错误信息使用 '__all__' 代表所有字段
error_messages = {
'__all__': {
'required': '必填',
'invalid': '格式错误'
},
}
生成html浏览器查看效果
-------------------------------------------
field_classes 更改原有字段生成的html标签类型
views.py
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
from django.forms import fields as form_fields
field_classes = {
'email':form_fields.URLField
}

-------------------------------------------------------------------------------------------------
localized_fields=('birth_date',) # 将数据本地化显示,如:根据不同时区显示数据
前提:
需要在settings.py中设置好本地的时区
# setting中的配置
TIME_ZONE = 'Asia/Shanghai' # 时区
USE_TZ = True # 启用本地时区
views.py
localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
# 如数据库中存的 2016-12-27 04:10:57
# 则前端显示:2016-12-27 12:10:57
ModelForm 的数据库保存方式
验证有效,直接使用验证实例.save() 保存到数据库
views.py
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj}) def post(self, request):
# 获取所有数据
# 每条数据请求的验证
# 成功显示正确信息
# 失败,给出错误提示
# 验证时将request.POST 传递给验证类,实例化验证对象
# verify_obj = MyFm(request.POST)
verify_obj = UserInfoModelForm(request.POST)
if verify_obj.is_valid():
# 默认保存多对多 :第三张表的数据
verify_obj.save()
# 不做任何操作,内部定义 save_m2m(用于保存多对多)
#verify_obj.save(commit=False)
#verify_obj.save() # 保存单张表信息
#verify_obj.save_m2m() # 保存关联多对多 第三张表的信息
models.py
数据表结构UserInfo UserType UserGroup
UserInfo ---> UserType 一对多
UserInfo<----> UserGroup 多对多
class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self):
return self.caption class UserGroup(models.Model):
name = models.CharField(max_length=32) class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to=UserType, to_field='id', on_delete=models.SET_NULL,null=True)
u_in_g = models.ManyToManyField(UserGroup)

-----------------------------------------------------------------------
应用案例:用户列表 查看/编辑用户信息,保存到数据库
models.py
UserInfo 表 user_type字段外键UserType id字段
UserInfo 表u_in_g 字段外键 多对多 UserGroup表id字段
from django.db import models # Create your models here. class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self):
return self.caption class UserGroup(models.Model):
name = models.CharField(max_length=32) def __str__(self):
return self.name class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to=UserType, to_field='id', on_delete=models.SET_NULL,null=True)
u_in_g = models.ManyToManyField(UserGroup)
查已保存的数据信息展示给前端
ModelForm 指定instance 数据对象(自定义的数据表 具体的查询结果对象),可以显示给前端
例如:user_html_obj = UserInfoModelForm(instance=user_data)
更新数据库中的信息
例如:
user = models.UserInfo.objects.filter(id=uid).first()
mf_obj = UserInfoModelForm(request.POST, instance=user)
mf_obj.save()
验证post请求的数据有效。更新到指定的查询结果中去,如果不指定instance 则为新增数据操作
views.py
class UserList(View):
def get(self, request):
users = models.UserInfo.objects.all().select_related('user_type')
return render(request, 'modelForm_user_lisst.html' , {'users': users}) class UserEdit(View):
def get(self, request, uid):
user_data = models.UserInfo.objects.filter(id=uid).first()
print('数据查询:', type(user_data))
# 将数据库查询出来的数据对象
user_html_obj = UserInfoModelForm(instance=user_data)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': user_html_obj, 'uid': uid})
pass def post(self, request,uid):
user = models.UserInfo.objects.filter(id=uid).first()
mf_obj = UserInfoModelForm(request.POST, instance=user)
# 更新的数据符合要求,保存到数据库
if mf_obj.is_valid():
mf_obj.save()
else:
print(mf_obj.errors.as_json)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': mf_obj, 'uid': uid})

modelForm的钩子
验证顺序:is_valid-->full_clean-->clean_fields-->clean_form-->_post_clean
1、在验证数据合法,保存到数据库之前,对验证的数据进行修改
定义 def clean_字段名():函数 对self.cleaned_data中获取到的字段进行修改
class UserInfoModelForm(forms.ModelForm):
class Meta(object):
#..................... def clean_username(self):
old_username = self.cleaned_data.get('username')
return old_username + '呵呵'

增加不存储于数据库的字段
应用场景:是否记住登录
views.py
from django.shortcuts import render
from django.views import View
from django import forms from modelForm_study import models
from django.forms import widgets as forms_widgets
# Create your views here. class UserInfoModelForm(forms.ModelForm): # 在生成前端标签的时候增加的字段(相比数据库表里面的字段)
rember_login = forms.CharField(
widget=forms_widgets.CheckboxInput(),
required=False # 是否必填
)
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
from django.forms import fields as form_fields
# field_classes = { # 改变原有字段类型
# 'email':form_fields.URLField
# }
error_messages = {
'__all__': {
'required': '必填',
'invalid': '格式错误'
},
'email': {
'required': '必填',
'invalid': '邮箱格式错误'
},
'username': {
'max_length': '太长了',
'min_length': '太短了',
}
}
help_texts = { # 提示信息
'username': '用户名哦',
'email': '邮箱啊'
}
labels = { # 生成html标签的对应input标签前面的提示
'username': 'lables 用户名',
'email': '邮箱',
'user_type': '用户类型',
'u_in_g': '所在组',
}
# widgets = {
# 'username': forms_widgets.Textarea(attrs={'class': 'test-class'})
# }
# fields = ['username', ]
# exclude = ['username'] # def clean_username(self):
# old_username = self.cleaned_data.get('username')
# return old_username + '呵呵'
# 请求处理 class UserList(View):
def get(self, request):
users = models.UserInfo.objects.all().select_related('user_type')
return render(request, 'modelForm_user_lisst.html' , {'users': users}) class UserEdit(View):
def get(self, request, uid):
user_data = models.UserInfo.objects.filter(id=uid).first()
print('数据查询:', type(user_data))
# 将数据库查询出来的数据对象
user_html_obj = UserInfoModelForm(instance=user_data)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': user_html_obj, 'uid': uid})
pass def post(self, request,uid):
user = models.UserInfo.objects.filter(id=uid).first()
mf_obj = UserInfoModelForm(request.POST, instance=user)
# mf_obj = UserInfoModelForm(request.POST) # 更新的数据符合要求,保存到数据库
if mf_obj.is_valid():
print(mf_obj.cleaned_data)
mf_obj.save()
if mf_obj.cleaned_data.get('rember_login'):
# 记住登录用户xxx时间内免登陆,设置cookie ,session等
print('是否记住登录:', mf_obj.cleaned_data.get('rember_login'))
else:
print(mf_obj.errors.as_json)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': mf_obj, 'uid': uid})
Django ModelForm表单验证的更多相关文章
- python运维开发(十九)----Django后台表单验证、session、cookie、model操作
内容目录: Django后台表单验证 CSRF加密传输 session.cookie model数据库操作 Django后台Form表单验证 Django中Form一般有2种功能: 1.用于做用户提交 ...
- django form表单验证
一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html ...
- django from表单验证
django from表单验证 实现:表单验证 工程示例: urls.py 1 2 3 4 5 6 7 8 9 from django.conf.urls import url from djan ...
- Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)
一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...
- Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)
通常验证用户输入是否合法的话,是前端js和后端共同验证的,这是因为前端js是可以被禁用的,假如被禁用了,那就没法用js实现验证合法与否了,也就是即使用户输入的不合法,但是也没提示,用户也不知道怎么输入 ...
- django book表单验证学习
django提供了强大的表单验证功能form 个人认为是把html代码封装到form里面,就像封装models中的数据一样.而且带有强大的验证功能,不需要后台再去写一堆乱七八糟的验证 具体操作查看dj ...
- Django之表单验证
对于前端的表单进行验证的方法,从最简单的js到基于XML传输的Ajax,再到cookie的免认证,现在Django为我们提供了自带的表单验证方法. views.py: from django impo ...
- 使用ModelForm表单验证
1.定义model.py model中定义的字段类型,只有在通过form进行验证的时候才有效,数据库中的字段类型与其并不完全一致,如数据库中并没有ipaddress类型.如果不通过form对字段进行验 ...
- django form 表单验证
随机推荐
- [Cnoi2020]线性生物
期望入门题.但是我不会做. 考虑设\(E_{x\to{x+1}}\)为\(x\)到\(x+1\)点的期望步数. 则\(ans = \sum_{i = 0}^{n} E_{x\to{x+1}}\) 知\ ...
- Codeforces 848D - Shake It!(DP)
Codeforces 题面传送门 & 洛谷题面传送门 hot tea 一道. 首先我们考虑这个奇奇怪怪的最小割有什么等价的表达.不难发现,如果我们选择了 \(S\to T\) 这条边并加入了一 ...
- python-django-数据查询条件
查询用户的状态是2或者是4的情况 空值和空字符串是不一样的东西!!! 需要注意的是: 项目setting.py里面的时区采用的是美国的时区,我们不要使用这个时区 使用这个时区的,我们输入的日期会进行转 ...
- mingling
mysql> USE mon Reading table information for completion of table and column names You can turn of ...
- Python中pymysql基本使用
Python中pymysql模块通过获取mysql数据库命令行游标执行数据库命令来进行数据库操作 优点:操作数据库语句所见即所得,执行了什么数据库语句都很清楚 缺点:操作繁琐,代码量多 1. pymy ...
- 学习Java的第三天
一.今日收获 1.今天家里有白事,忙了一整天,也没有看更多的资料 二.今日问题 无 三.明日目标 补全今天耽误的功课,继续学习java!
- accurate, accuse
accurate accurate(不是acute)和precise是近义词,precise里有个pre,又和excise(切除, 不是exercise),concise一样有cise.Why? 准确 ...
- 寻找pair
给定n个整数使其两两组合成一对pair,例如给定 1 ,2 可以组成的pair为(1,1),(1,2),(2,1),(2,2),然后在这些pair中寻找第k小的pair. 输入第一行包含两个数字,第一 ...
- zabbix实现对主机和Tomcat监控
#:在tomcat服务器安装agent root@ubuntu:~# apt install zabbix-agent #:修改配置文件 root@ubuntu:~# vim /etc/zabbix/ ...
- 软件测试人员必备的linux命令
1 目录与文件操作1.1 ls(初级)使用权限:所有人功能 : 显示指定工作目录下之内容(列出目前工作目录所含之档案及子目录). 参数 : -a 显示所有档案及目录 (ls内定将档案名或目录名称开头为 ...