在Flask web开发实践中,常常会涉及到表单的提交和验证,flask的插件flask-wtf提供了很多表单验证的方法,但是目前所知这些表单验证都需要提交后再验证,不能做到当用户输入完用户名就能检查用户名格式是否正确
最近学习了点Jquery和Ajax,这次写JQuery Validation插件+Ajax的实时表单验证的过程中遇到了很多小问题,在网上搜索也没有找到这方面的项目整合经验,所以将自己最后写好的代码做一个笔记,希望可以帮到其他人。
先贴结果图:
从图片可以看出,在表单验证时,除了进行简单的长度,邮箱格式等验证外,还通过Ajax与服务端进行信息交互,检查用户输入的邮箱是否已经注册以及用户名密码是否与服务端数据库匹配。
下面开始贴代码:
1.用户类User,使用Flask-SQLALCHEMY方便数据库操作
class User(UserMixin,db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer,primary_key=True)
email = db.Column(db.String(128),unique=True,index=True)
password_hash = db.Column(db.String(128))
def __init__(self,email,username,password,telephone):
self.email = email
self.password_hash = generate_password_hash(password)
@property
def password(self):
raise AttributeError('password is not a readable attribute')
def verify_password(self,password):
return check_password_hash(self.password_hash,password)
@password.setter
def password(self,password):
self.password_hash = generate_password_hash(password)
def __repr__(self):
return '<User %r>' % self.username
2.登录页面:login.html
2.1 引入JQuery和Jquery Vlidation,bootstrap
<link rel="stylesheet" href="{{ url_for('static',filename='bootstrap/css/bootstrap.css') }}">
<script src="{{ url_for('static',filename='js/jquery-3.2.1.js') }}"></script>
<script src="{{ url_for('static',filename='js/jquery.validate.js') }}"></script>
2.2 表单的设计
<form class="form-horizontal" role="form" id="loginForm" method="post" action="{{url_for('user.login')}}">
<div class="form-group">
<label for="email" class="col-sm-3 control-label">邮箱:</label>
<div class="col-sm-7">
<input type="text" name="email" id="email" class="form-control">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-3 control-label">密码:</label>
<div class="col-sm-7">
<input type="password" name="password" id="password" class="form-control">
<p class="help-block" id="helpmessage"></p>
</div>
</div>
<div class="form-group">
<span class="col-sm-3">
</span>
<span class="col-sm-7">
<input type="submit" class="btn btn-success btn-block" value="登 录">
</span>
</div>
</form>
2.3 Jquery Validation+Ajax验证表单的字段
<script>
$(document).ready(function(){
var validator;
validator = $("#loginForm").validate({
rules:{
email:{ //为name="email"的控件添加验证
required:true, //必填
email:true, //邮箱规范
minlength:6, //最小长度为6
maxlength:20, //最大长度为20
remote:{ //将用户输入信息返回服务端,当用户返回true时表示验证通过,当用户返回false时输出messages中对应错误信息
url:"/user/loginvalidate/email", // 接收远程验证的地址
type:"post",
data:{
email:function(){return $("#email").val();}
}
}
},
password:{
required:true,
minlength:6,
maxlength:15,
validateUser:true //自定义验证方法用于验证密码是否正确
}
},
messages:{ //自定义提示信息
email:{
required:"邮箱必填",
minlength:"最小长度为6",
maxlength:"最大长度为20",
email:"邮箱格式不正确",
remote:"邮箱未注册"
},
password:{
required:"密码必填",
minlength:"密码最小长度为6",
maxlength:"密码最大长度为15"
}
},
errorPlacement: function(error, element) { //错误信息的位置
error.appendTo( element.parent() );
}
});
$.validator.addMethod( //添加自定义验证函数
"validateUser", //自定义验证函数的名称
function(value,element,params){
$.ajax({ //发送Ajax请求
type:"POST",
url:"/user/validate/password",
dataType:"json", //数据类型为json,发回的数据已自动解析
data:{
email:function(){return $("#email").val();},
password:function(){return $("#password").val();}
},
success:function(data){
if(!data){ //根据返回的信息在指定位置提示用户
$("#helpmessage").html("用户名或密码错误");
}else
$("#helpmessage").html("");
}
});
return true;
},
"用户名或密码错误"
);
});
</script>
3.view.py代码
3.1 登录页面处理
@user.route('/login', methods=['POST','GET'])
def login():
if request.method == "GET": #当请求方法为get时,返回html页面
return render_template("user/login.html")
else: #当请求方法为post时,处理表单提交的信息
email = request.form.get("email") #获取表单的字段
password = request.form.get("password")
user = User.query.filter_by(email=email).first() #查找数据库中是否存在,如果不存在user为None
if user.verify_password(password): #查找密码是否对应
login_user(user) #用户会话管理flask-login插件中记录用户的登录状态
return redirect(request.args.get('next') or url_for('main.home'))
flash("用户名或密码错误!")
return redirect(url_for('.login'))
3.2 检查用户输入邮箱是否已注册的代码
#登录检查邮箱是否已注册
@user.route('/loginvalidate/email',methods=['POST','GET'])
def validateemail2():
email = request.form.get('email') #获取用户输入的邮箱
if User.query.filter_by(email=email).first(): #当查询结果不为空,说明邮箱已注册可以登录
return jsonify(True) #返回json数据true
return jsonify(False) #当返回false时,jquery validation中的messages中对应的信息将会显示在输入框后面
3.3 检查用户名密码与数据库中是否对应的代码
#检查用户名密码是否正确
@user.route('/validate/password',methods=['POST','GET'])
def validatepassword():
email = request.form.get("email") #获取用户输入的信息
password = request.form.get("password")
user = User.query.filter_by(email=email).first()
if user is not None and user.verify_password(password): #若与数据库中用户名密码匹配,返回true
return jsonify(True) #返回json数据true,接收方会自动解析,当返回true时不显示信息
return jsonify(False) #当返回false时显示“用户名或密码错误
代码就是这样啦,写代码过程中遇到最多的就是Ajax请求数据的封装和解析,根本上还是对json不了解
大家有什么建议欢迎提,西西