Django中的Form表单验证
回忆一下Form表单验证的逻辑:
前端有若干个input输入框,将用户输入内容,以字典传递给后端。
后端预先存在一个Form表单验证的基类,封装了一个检测用户输入是否全部通过的方法。该方法会先定义好错误信息的字典,并会遍历类的所有属性(对应前端待验证的输入域),调用各自的验证方法,将错误信息(两类,必要与否以及格式正确与否)存入字典,并得出最终的验证结果。在使用时,需要定义继承自Form基类不同的Form类,以对应有着不同输入域的Form表单。在拿到前端给的字典前,要先初始化自定义From类,直接执行封装好的整体验证方法,拿到结果后就可以抛给前端了。
Django中Form表单验证涉及到的知识:
1.Django中的ErrorDcit类如何封装了错误信息
- # project/app01/forms.py
- from django import forms
- # 继承自Django的Form类
- # 内部以字段形式定义验证域
- class MyForm(forms.Form):
- user = forms.CharField()
- pwd = forms.CharField()
- # project/app01/views.py
- def form(request):
- from app01.forms import MyForm
- if request.method == 'POST':
- f = MyForm(request.POST)
- ret = f.is_valid() # bool
- data = f.cleaned_data # {'user': 'asd', 'pwd': 'asd'}
- errors = f.errors # ErrorDict,打印时因为__str__方法,会显示位ul标签的形式
- print(errors.get('user', None)[0] if errors.get('user', None) else None) # ErrorList,以索引取出第一条错误信息
- return render(request, "form.html", {"errors": f.errors})
- return render(request, "form.html")
- # project/templates/forms.html
- <form action="/form/" method="post">
- <div>
- 用户名:<input type="text" name="user"/>
- </div>
- <div>
- 密码:<input type="password" name="pwd"/>
- </div>
- <div>
- <input type="submit" value="提交"/>
- </div>
- {{ errors }}
- <div></div>
2.抛给前端的ErrorDcit及使用模板语言漂合理展示
展示错误信息的前端布局
通过返回Form类和模板语言在前端动态生成input标签
- # project/app01/views.py
- def form(request):
- from app01.forms import MyForm
- empty_form = MyForm()
- if request.method == 'POST':
- f = MyForm(request.POST)
- if f.is_valid():
- print(f.cleaned_data)
- # 这里只是为了使得正确提交后不至于让input消失,实际坏境中这里应该是用户信息验证
- return render(request, "form.html", {'myform': empty_form})
- return render(request, "form.html", {"errors": f.errors, "myform": f})
- else:
- return render(request, "form.html", {'myform': empty_form})
- # project/templates/forms.html
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .input-group{
- padding: 15px;
- }
- .input-group input{
- width: 200px;
- }
- .input-group span{
- display: inline-block;
- position: relative;
- border: 1px solid red;
- top: 25px;
- left: -211px;
- }
- </style>
- </head>
- <body>
- <form action="/form/" method="post">
- <div class="input-group">
- <div style="float:left;width:70px;">用户名:</div>
- {{ myform.user }}
- {% if errors.user.0 %}
- <span>{{ errors.user.0 }}</span>
- {% endif %}
- </div>
- <div class="input-group">
- <div style="float:left;width:70px;">密码:</div>
- {{ myform.pwd }}
- {% if errors.pwd.0 %}
- <span>{{ errors.pwd.0 }}</span>
- {% endif %}
- </div>
- <div>
- <input style="float:left;margin-left:15px;" type="submit" value="提交"/>
- </div>
- </form>
4.django.forms中的CharField参数
(required, min/max_length,error_messages,forms.widget)
不重启服务时数据库数据动态更新到前端(静态字段的特点)
field不合需求时自定义验证规则(validators参数)
- # project/app01/forms.py
- from django import forms
- from app01 import models
- def mobile_validate(value):
- import re
- mobile_re = re.compile("^(13[0-9]|14[579]|15[0-3,5-9]|1 6[6]|17[0135678]|18[0-9]|19[89])\\d{8}$")
- if not mobile_re.match(value):
- print('')
- raise forms.ValidationError('手机号码格式不对哦')
- class MyForm(forms.Form):
- def __init__(self, *args, **kwargs):
- super(MyForm, self).__init__(*args, **kwargs)
- self.fields['book_type'] = forms.CharField(
- widget=forms.Select(choices=models.BookType.objects.values_list('id', 'caption'))
- )
- user = forms.CharField(min_length=4, max_length=10, widget=forms.TextInput)
- pwd = forms.CharField(error_messages={'required': '为什么不输入密码??'})
- email = forms.EmailField(error_messages={'required': '邮箱还没输入哦', 'invalid': '邮箱格式错误'})
- # book_type_choices = (
- # (0, '小说'), value
- # (1, '科普'), innerText
- # ) # 元组内有元组
- # 从数据库获得数据
- # 注意这里filed都是静态字段
- # 类的静态字段只创建一次以后不会再修改,新的对象都会使用同一份数据
- # 所以MyForm这里的静态字段只会执行一次
- # 加入数据库中的数据更新了,服务器不重启的话,这里从数据库取来的值是不会变的
- # 因此将该字段写入类的初始化方法里,不要忘了执行父类的初始化方法哦
- # book_type_choices = models.BookType.objects.values_list('id', 'caption')
- # book_type = forms.CharField(
- # widget=forms.Select(choices=book_type_choices)
- # )
- comment = forms.CharField(
- widget=forms.Textarea(attrs={'style': 'border:1px solid red;'})
- ) # 可以为生成的标签添加属性
- mobile = forms.CharField(
- validators=[mobile_validate, ],
- error_messages={'required': '手机号不填不行'},
- widget=forms.TextInput
- )
- <div class="input-group">
- <div style="float:left;width:70px;">用户名:</div>
- {{ myform.user }}
- {% if errors.user.0 %}
- <span>{{ errors.user.0 }}</span>
- {% endif %}
- </div>
- <div class="input-group">
- <div style="float:left;width:70px;">密码:</div>
- {{ myform.pwd }}
- {% if errors.pwd.0 %}
- <span>{{ errors.pwd.0 }}</span>
- {% endif %}
- </div>
- <div class="input-group">
- <div style="float:left;width:70px;">邮箱:</div>
- {{ myform.email }}
- {% if errors.email.0 %}
- <span>{{ errors.email.0 }}</span>
- {% endif %}
- // 以下都是上面input-group标签的重复,只是field不同而已,不再细说
碎碎念:
中间给render传入两个字典,一直调试不出问题,费时颇久,下次留心。
Django中的Form表单验证的更多相关文章
- 第三百一十一节,Django框架,Form表单验证
第三百一十一节,Django框架,Form表单验证 表单提交 html <!DOCTYPE html> <html lang="en"> <head& ...
- Django 中的Form表单认证
一.Form表单 1.1 Form的几个功能 验证用户数据(显示错误信息) 初始化页面显示内容 HTML Form提交保留上次提交数据 生成HTML标签 1.2 创建表单类Form 1. 创建 ...
- Django基础之Form表单验证
Form表单验证 1.创建Form类(本质就是正则表达式的集合) from django.forms import Form from django.forms import fields from ...
- Django中的Form表单
Django中已经定义好了form类,可以很容易的使用Django生成一个表单. 一.利用Django生成一个表单: 1.在应用下创建一个forms文件,用于存放form表单.然后在forms中实例华 ...
- django中的 form 表单操作
form组件 1. 能做什么事? 1. 能生成HTML代码 input框 2. 可以校验数据 3. 保留输入的数据 4. 有错误的提示 1. 定义 from django ...
- the django travel three[form表单验证]
一:表单验证: 场景:因为浏览器的js可以被禁用,所以需要做后台的输入合法的验证. A:ajax发请求.需要注意的是ajax POST的数据的key值和form表单的里的字段名字一致,否则得不到验证! ...
- 九 Django框架,Form表单验证
表单提交 html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- django中写form表单时csrf_token的作用
之前在学习django的时候,在template中写form时,出现错误.百度,google后要加{% csrf_token %}才可以,之前一直也没研究,只是知道要加个这个东西,具体是什么也不明白. ...
- django中使用form表单,数据库保存密码出现明文
随机推荐
- C++回顾day03---<类型转换>
一:C++类型转换 (一)static_cast<>() 静态类型转换:基本类型可以转换但是指针类型不允许.可以进行隐式类型转换 double n=1.23 int m=static_ca ...
- Linux shell脚本启动 停止 重启jar包
最近做的微服务jar包想弄在持续集成中自动化部署,所以首先得有一个操作jar包的脚本 只需将jar文件的路径替换到APP_NAME的值就可以了,其他不用改 注意:window编辑的shell文件,通过 ...
- Git 分支 (二)合并
分支的新建与合并 让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流. 你将经历如下步骤:1. 开发某个网站.2. 为实现某个新的需求,创建一个分支.3. 在这个分支上开 ...
- 基于alpine制作php镜像
alpine包搜索https://pkgs.alpinelinux.org/ 安装依赖库 apk add --no-cache xxx 可以基于php apline镜像自行增加或删除扩展. https ...
- 抓包工具Charles基本用法
我们在进行B/S架构的Web项目开发时,在前端页面与后台交互的调试的时候,通常使用在JSP中加入“debugger;”断点,然后使用浏览器的F12开发者工具来查看可能出错的地方的数据.或者使用Http ...
- [物理学与PDEs]第5章习题9 伴随矩阵的特征值
设 $3\times 3$ 阵 ${\bf A}$ 的特征值为 $\lm_1,\lm_2,\lm_3$, 证明 $\cof {\bf A}$ 的特征值为 $$\bex \lm_2\lm_3,\quad ...
- [译]Ocelot - Middleware Injection and Overrides
原文 使用这个特性的时候要小心点. 可以如下一样提供一些中间件用以覆盖默认的中间件: var configuration = new OcelotPipelineConfiguration { Pre ...
- SSRF漏洞挖掘经验
SSRF概述 SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞.一般情况下,SSRF攻击的目标是从外网无法访问 ...
- Thread和Runnable的区别
Runnable源码 Thread源码 结论 Thread实现了Runnable接口的类,使得run支持多线程. 因类的单一继承原则,推荐使用Runnable接口实现多线程
- Fatal error: cannot initialize AIO sub-system
在一台服务器中以各数据库的备份文件为数据文件启动多个MySQL实例供SQL Review使用.之前运行一直没有问题(最多的时候有23个MySQL实例同时运行),后来新配置了一台服务器,启动其对应的实例 ...