Flask form表单校验
flask 中需要安装 flask-wtf,安装命令:pip install flask-wtf
首先创建一个form.py
#!/usr/bin/env python
#-*-coding:utf-8-*-
#导入模块
from flask_wtf import FlaskForm #FlaskForm 为表单基类
from wtforms import StringField,PasswordField,SubmitField #导入字符串字 段,密码字段,提交字段
from wtforms.validators import DataRequired,ValidationError
from models import Admin #从models导入模型(表)
#定义登录表单,并且需要在视图函数(views.py)中实例化
class LoginForm(FlaskForm):
account = StringField(
# 标签
label="账号",
# 验证器
validators=[
DataRequired('请输入用户名')
],
description="账号",
# 附加选项,会自动在前端判别
render_kw={
"class":"form-control",
"placeholder":"请输入账号!",
"required":'required' #表示输入框不能为空,并有提示信息
}
)
pwd = PasswordField(
# 标签
label="密码",
# 验证器
validators=[
DataRequired('请输入密码')
],
description="密码",
# 附加选项(主要是前端样式),会自动在前端判别
render_kw={
"class": "form-control",
"placeholder": "请输入密码!",
"required": 'required' # 表示输入框不能为空
}
)
submit = SubmitField(
label="登录",
render_kw={
"class": "btn btn-primary btn-block btn-flat",
}
)
views.py 视图函数
from . import adminbapp ##导入appfrom flask import render_template,redirect,url_for,flash,session,requestfrom admin.forms import LoginForm #引入forms.py文件from models import Admin #导入数据库模型from functools import wraps #导入装饰器模块from movie_project import db #引入sqlalchemy实例化对象#登录验证装饰器def login_required(func):
@wraps(func) def decorated_function(*args, **kwargs): if session.get('admin'): #验证session return func(*args, **kwargs) else: return redirect(url_for('admin.login')) return decorated_function
@adminbapp.route('/login/',methods=['GET','POST'])
def login():
forms = LoginForm() #实例化forms
if forms.validate_on_submit(): #提交的时候进行验证,如果数据能被所有验证函数接受,则返回true,否则返回false
data = forms.data #获取form数据信息(包含输入的用户名(account)和密码(pwd)等信息),这里的account和pwd是在forms.py里定义的
admin = Admin.query.filter_by(name=data["account"]).first() #查询表信息admin表里的用户名信息
if admin == None:
flash("账号不存在") #操作提示信息,会在前端显示
return redirect(url_for('admin.login'))
elif admin != None and not admin.check_pwd(data["pwd"]): #这里的check_pwd函数在models 下Admin模型下定义
flash("密码错误")
return redirect(url_for('admin.login'))
session['admin'] = data['account'] #匹配成功,添加session
return redirect(request.args.get('next') or url_for('admin.index')) #重定向到首页
return render_template('admin/login.html',form=forms)
数据库模型models.py
class Admin(db.Model):
__tablename= 'admin'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False, unique=True) # unique代表不能重复,唯一的
pwd = db.Column(db.String(100), nullable=False)
is_super = db.Column(db.SmallInteger) #是否为超级管理员
role_id = db.Column(db.Integer,db.ForeignKey('role.id'))
addtime = db.Column(db.DateTime, index=True, default=datetime.datetime.now)
adminlogs = db.relationship('Adminlog',backref='admin')
adminoption = db.relationship('Oplogs', backref='admin')
def __repr__(self):
return '<Admin %r>' % self.name
#定义密码验证函数
def check_pwd(self,pwd):
from werkzeug.security import check_password_hash #由于密码是加密的,所以要引入相应的加密函数
return check_password_hash(self.pwd,pwd)
前端 login.html
<div class="login-box-body">
{% for msg in get_flashed_messages() %} <!--这里对应视图函数里定义的提示信息 flash-->
<p class="login-box-msg" style="color: red;">{{ msg }}</p> <!--信息在前端显示-->
{% endfor %}
<form method="POST" id="form-data"> <!--使用form,这里可以不用写action-->
<div class="form-group has-feedback">
{{ form.account }} <!--常规情况下,这里应该为一个input框,用来定义用户输入,由于在forms里已经定义,这里直接调用就行-->
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
{% for err in form.account.errors %} <!--错误信息-->
<div class="col-md-12">
<span style="color: red">{{ err }}</span> <!--显示错误信息-->
</div>
{% endfor %}
</div>
<div class="form-group has-feedback">
{{ form.pwd }} <!--同上面的用户输入-->
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
{% for err in form.pwd.errors %} <!--pwd输入错误的提示信息-->
<div class="col-md-12">
<font style="color: red">{{ err }}</font>
</div>
{% endfor %}
</div>
<div class="row">
<div class="col-xs-8">
</div>
<div class="col-xs-4">
{{ form.submit }} <!--提交按钮-->
{{ form.csrf_token }} <!--csrftoken必须要写,同时还要设置 app的secret_key-->
</div>
</div>
</form>
</div>
配置secret_key
import os
app.config['SECRET_KEY'] = os.urandom(24)
django中form表单校验
创建form.py
django中form表单校验自带,不需要安装
1、先导入forms模块
1
from django import forms
2、创建模板的类
# 1、创建模板
class loginform(forms.Form):
# 2、模板中的元素
name = forms.CharField(min_length=6,error_messages={"requird":"用户名不能为空","min_length":"最小长度为6"})
# requird这个是错误码
email = forms.EmailField()
这里这个error_messages写出错的信息,每个不同的错误码对应不同的报错信息
3、在视图函数中使用这个类
def login(request):
if request.method.lower() == "post":
# 3、创建一个模板的对象,然后把数据传递个这个对象
obj = loginform(request.POST)
# 4、启动校验
status= obj.is_valid()
print(status)
# 5、正确的信息
success_dict = obj.clean()
print(success_dict)
# 6、错误的信息
failed_dict = obj.errors.as_json()
print(failed_dict)
return redirect("/app1/login")
else:
return render(request,"login.html")
这里就会校验前台发来的数据中,k为name和email的值的合法性
###html文件
与flask中基本相同,注意input属性中 name =" ",一定要与form表单对应
###后端代码
因为是form表单,所以提交后页面会刷新,上次输入的数据就没有了,我们可以通过下面的方式实现保留上次输入的值
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
# Create your views here.
from django import forms
"""
def login(request):
if request.method.lower() == "post":
print(request.POST.get("name"))
return redirect("/app1/login")
else:
return render(request,"login.html")
# return redirect("/app1/login")
# return HttpResponse("hahh")
"""
# 1、创建模板
class loginform(forms.Form):
# 2、模板中的元素
name = forms.CharField(min_length=6,error_messages={"required":"用户名不能为空","min_length":"最小长度为6666666666"})
# requird这个是错误码
email = forms.EmailField(error_messages={"required":"邮箱不能为空","invalid":"邮箱格式错误"})
def login(request):
if request.method.lower() == "post":
# 3、创建一个模板的对象,然后把数据传递个这个对象
obj = loginform(request.POST)
# 4、启动校验
status= obj.is_valid()
print(status)
# 5、正确的信息
success_dict = obj.clean()
print("正确的信息----------->",success_dict)
# 6_1、错误的信息1
# failed_dict = obj.errors.as_json()
# 6_2、错误的信息1
failed_dict = obj.errors
if not obj.is_valid():
# print(failed_dict["name"])
# print(failed_dict["name"][0])
print("错误的信息----------->",failed_dict)
print("名称的错误信息-------->",failed_dict["name"][0])
print("邮箱的错误信息-------->", failed_dict["email"][0])
return render(request, "login.html", {'xx': obj})
# return redirect("/app1/login")
else:
obj = loginform()
# return render(request,"login.html")
# return redirect("/app1/login")
return render(request,"login.html",{"xx":obj})
# return HttpResponse("hahh")
如果还有较为复杂的逻辑校验,上面的校验不能满足需求,需要定义clearn_方法
def clearn_name(self):
name = self.cleaned_data.get('name')
if name in ['admin']:
raise ValidationError('不能有敏感字符')
注意:clearn_是系统做完上面校验后自动调用,不需要自己调用。