开头寄语:

这几天一直在看Django的form表单验证,然后想对于这几天要有个总结。

  • 首先,先来看一下找到的一个form表单验证的流程:

验证过程


流程详解
1. 函数full_clean()依次调用每个field的clean()函数,该函数针对field的max_length,unique等约束进行验证,如果验证成功则返回值,否则抛出ValidationError错误。如果有值返回,则放入form的cleaned_data字典中。
2. 如果每个field的内置clean()函数没有抛出ValidationError错误,则调用以clean_开头,以field名字结尾的自定义field验证函数。验证成功和失败的处理方式同步骤1。
3. 最后,调用form的clean()函数——注意,这里是form的clean(),而不是field的clean()——如果clean没有错误,那么它将返回cleaned_data字典。
4. 如果到这一步没有ValidationError抛出,那么cleaned_data字典就填满了有效数据。否则cleaned_data不存在,form的另外一个字典errors填上验证错误。在template中,每个field获取自己错误的方式是:{{ form.username.errors }}。
5. 最后,如果有错误is_valid()返回False,否则返回True。
注意一点:自定义验证机制时:clean()和clean_<field>&()的最后必须返回验证完毕或修改后的值.

  • 补充小插曲

我们在写表单类的时候 一般也继承froms.Form,但是也见过继承ModleForm,应该来说继承那个都可以,个人认为继承ModleForm时,主要是再写表单类的时候方便些,比如通过如下方式写表单类

from app01.models import Moment
from django import forms
from django.forms import ModelForm class MomentForm(ModelForm): class Meta:
model = Moment # Models类名称
fields = "__all__" # 导入所有的字段
# fields = ['content', 'user_name']
  • 下面是自己写的一个小实例,内容包括 form表单验证与session

需求如下:

用户访问首页,在首页点击注册,对注册表单进行验证,登录成功后进入后台管理界面

表单类:

表单中包含input标签 select标签 checkbox标签 也定义了一些自定义的验证逻辑,这里也看了一些资料,我认为在定义clean_xx 函数时 最后要return 验证字段的值,而重写clean()方法时,最后要return clean_data。

# 注册页面手机号验证
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
value = str(value)
if not mobile_re.match(value):
raise forms.ValidationError('手机号码格式错误') class RegisterForm(forms.Form):
username = forms.CharField(
error_messages={'required': '用户名不能为空', 'min_length': '最小长度为4', 'max_length': '最大长度为30'},
max_length=30,
min_length=4,
) password = forms.CharField(
error_messages={'required': '密码不能为空'}
) password_again = forms.CharField(
error_messages={'required': '密码不能为空',}
)
email = forms.EmailField(
required=False,
error_messages={'invalid': '邮箱格式错误'}
)
phone = forms.IntegerField(validators=[mobile_validate],
error_messages={'required': '手机号不能为空', 'invalid': '必须输入数字'}
)
roles = Role.objects.all().values_list('id', 'role_name')
role = forms.CharField(
error_messages={'required': '角色不能为空'},
widget=forms.widgets.Select(choices=roles, attrs={'class': 'c1'}))
marry_choice = (
('', '男'),
('', '女'),
('', '已婚'),
('', '未婚'),
)
marry = forms.MultipleChoiceField(
error_messages={'required': '选择不能为空'},
choices=marry_choice, widget=forms.CheckboxSelectMultiple()) favors = Favor.objects.all().values_list('id', 'favor_name')
favor = forms.CharField(
error_messages={'required': '爱好不能为空'},
widget=forms.widgets.Select(choices=favors, attrs={'class': 'c1', 'multiple': 'multiple'}))
code = forms.CharField(
error_messages={'required': '验证码不能为空'}
) # 自定义验证 验证password
def clean_password(self):
cleaned_data = super(RegisterForm, self).clean()
user_data = cleaned_data.get('password')
if user_data == 'XXX':
raise forms.ValidationError(u'密码太简单了')
return user_data # 验证两次输入的密码是否一致
def clean_password_again(self):
password = self.cleaned_data['password']
password_again = self.cleaned_data['password_again']
if password != password_again:
raise forms.ValidationError('两次密码不一致')
return password_again def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
self.fields['role'] = forms.CharField(
widget=forms.widgets.Select(choices=Role.objects.all().values_list('id', 'role_name'), attrs={'class': 'c1'})
)
self.fields['favor'] = forms.CharField(
widget=forms.widgets.Select(choices=Favor.objects.all().values_list('id', 'favor_name'),
attrs={'class': 'c1'})
) # 验证选择婚姻是否正确
def clean_marry(self):
data_list = self.cleaned_data['marry']
if len(data_list) == 2:
if '' and '' in data_list:
raise forms.ValidationError('男女选择有误!')
elif '' and '' in data_list:
raise forms.ValidationError('婚姻选择有误!')
else:
return data_list
else:
raise forms.ValidationError('请选择男女和婚姻!')

前段html

这里面 input标签 包括自己写的 也有 通过Django自动生成的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<link rel="stylesheet" type="text/css" href="/statics/css/one.css">
</head>
<body>
<div class="register-page">
<div class="mid-css">
<form method="post" action="/register/">
<div class="commons-css">
<span class="register-span">用户名:</span>
<input type="text" name="username" placeholder="请输入用户名">
<span class="error-info">{{ errors.username.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">密码:</span>
<input type="text" name="password" placeholder="请输入密码">
<span class="error-info">{{ errors.password.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">确认密码:</span>
<input type="text" name="password_again" placeholder="请输入密码">
<span class="error-info">{{ errors.password_again.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">邮箱:</span>
<input type="text" name="email" placeholder="请输入邮箱">
<span class="error-info">{{ errors.email.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">手机号:</span>
<input type="text" name="phone" placeholder="请输入手机号">
<span class="error-info">{{ errors.phone.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">角色:</span>
{{ form.role }}
<span class="error-info">{{ errors.role.0 }}</span>
</div> <div class="favor-css ClearFloat">
<span class="favor-span">婚姻状况:</span>
{{ form.marry }}
<span class="error-info">{{ errors.marry.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">爱好:</span>
{{ form.favor }}
<span class="error-info">{{ errors.favor.0 }}</span>
</div> <div class="commons-css">
<span class="register-span">验证码:</span>
<input type="text" name="code" style="width: 150px">
<span class="span-code" onclick= "GetCode(this)" id="span">点击获取</span>
{% if errors.code.0 %}
<span class="error-info">{{ errors.code.0 }}</span>
{% else %}
<span class="error-info">{{ code_error.error_code_info }}</span>
{% endif %}
</div>
<div class="register-submit">
<input type="button" value="重置">
<input type="submit" value="注册">
</div>
</form>
</div>
</div>
<script type="text/javascript" src="/statics/js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="/statics/js/one.js"></script>
</body>
</html>

后台处理:

def register(request):
if request.method == 'POST':
register_obj = RegisterForm(request.POST)
ret = register_obj.is_valid()
if ret:
input_code = register_obj.cleaned_data['code']
old_code = request.session['code']
if input_code.upper() == old_code.upper():
request.session['is_login'] = True
print(register_obj.cleaned_data)
return HttpResponseRedirect('/manager/')
else:
error_code_info = {'error_code_info': '验证码输入错误'}
return render(request, 'forms/register.html', {'errors': register_obj.errors,
'code_error': error_code_info, 'form': register_obj})
else:
return render(request, 'forms/register.html', {'errors': register_obj.errors, 'form': register_obj})
else:
register_obj = RegisterForm()
return render(request, 'forms/register.html', {'form': register_obj})

页面效果:

django Form 表单 总结与小实例的更多相关文章

  1. Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)

    一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...

  2. Django form表单 组件

    目录 Django form表单 组件 Form 组件介绍 普通方式手写注册功能 使用form组件实现注册功能 Form 常用字段与插件 常用字段(必备) 字段参数(必备) 内置验证(必备) 自定义效 ...

  3. django form表单验证

    一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html ...

  4. Django Form表单组件

    Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否 ...

  5. Django学习笔记之Django Form表单详解

    知识预览 构建一个表单 在Django 中构建一个表单 Django Form 类详解 使用表单模板 回到顶部 构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的 ...

  6. django Form表单的使用

    Form django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm 关于django的表单系统,主要分两种 基于django.forms.Form ...

  7. Django form表单

    Form介绍 之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入, ...

  8. python django Form表单

    Django 拥有自己独立的表单功能块,可以完成: 1.表单的定义 2.表单的校验 3.表单的前端样式 等功能,方便我们开发,那么接下来,我们看一下表单的定义 首先我们确定我们要编写的功能,一个提供给 ...

  9. Javascript和Java获取各种form表单信息的简单实例

    大家都知道我们在提交form的时候用了多种input表单.可是不是每一种input表单都是很简单的用Document.getElementById的方式就可以获取到的.有一些组合的form类似于che ...

随机推荐

  1. 科学计算三维可视化---TVTK入门(数据加载)

    一:数据加载 大多数可视化应用的数据并非是在TVTK库中构建的,很多都是通过接口读取外部数据文件 (一)使用vtkSTLReader来读取外部文件 .stl 文件是在计算机图形应用系统中,用于表示三角 ...

  2. Mongodb 笔记01 MongoDB 简介、MongoDB基础知识、启动和停止MongoDB

    MongoDB 简介 1. 易于使用:没有固定的模式,根据需要添加和删除字段更加容易 2. 易于扩展:MongoDB的设计采用横向扩展.面向文档的数据模型使它能很容易的再多台服务器之间进行分割.自动处 ...

  3. OpenResty 扩展库之(一)——lua-resty-shell 库

    介绍 当您需要执行子进程(或shell命令)时,这是一个打算与OpenResty应用程序一起使用的小型库. 它类似于os.execute和io.popen,除了它是完全非阻塞的,因此即使对于需要很长时 ...

  4. Ubuntu安装Nginx 问题以及解决办法

    Error1 the HTTP rewrite module requires the PCRE library sudo apt-get update sudo apt-get install li ...

  5. 阮一峰:自适应网页设计(Responsive Web Design)别名(响应式web设计)

    随着3G的普及,越来越多的人使用手机上网. 移动设备正超过桌面设备,成为访问互联网的最常见终端.于是,网页设计师不得不面对一个难题:如何才能在不同大小的设备上呈现同样的网页? 手机的屏幕比较小,宽度通 ...

  6. jQuery技巧笔记

    1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...

  7. R7—左右内全连接详解

    在SQL查询中,经常会用到左连接.右连接.内连接.全连接,那么在R中如何实现这些功能,今天来讲一讲! SQL回顾 原理 # 连接可分为以下几类: 内连接.(典型的连接运算,使用像   =   或   ...

  8. 【COGS】2287:[HZOI 2015]疯狂的机器人 FFT+卡特兰数+排列组合

    [题意][COGS 2287][HZOI 2015]疯狂的机器人 [算法]FFT+卡特兰数+排列组合 [题解]先考虑一维的情况,支持+1和-1,前缀和不能为负数,就是卡特兰数的形式. 设C(n)表示第 ...

  9. shell作业后台执行的方法

    来思考几种场景: 1.某个脚本需要执行时间比较长,无人值守,可能执行过程中因ssh会话超时而中断? 2.某次测试一段代码,需要临时放入后台运行? 3.放入后台运行的脚本,需要在一段时间后重新调到前台? ...

  10. 【译】第六篇 Replication:合并复制-发布

    本篇文章是SQL Server Replication系列的第六篇,详细内容请参考原文. 合并复制,类似于事务复制,包括一个发布服务器,一个分发服务器和一个或多个订阅服务器.每一个发布服务器上可以定义 ...