Flask实战第44天:完成前台注册功能
注册功能后端逻辑
用户注册要把注册的表单提交上来,因此,我要先对表单进行验证,编辑front.forms
from apps.forms import BaseForm from wtforms import StringField from wtforms.validators import Regexp, Length, EqualTo, ValidationError from utils import xcache from .models import FrontUser class SignUpForm(BaseForm): telephone = StringField(validators=[Regexp(r'1[35678]\d{9}', message='手机号码格式错误')]) sms_captcha = StringField(validators=[Regexp(r'\w{6}', message='短信验证码错误')]) username = StringField(validators=[Length(2,20, message='用户名格式错误')]) password1 = StringField(validators=[Length(5, 30, message='密码格式错误')]) password2 = StringField(validators=[EqualTo('password1', message='两次密码不一致')]) graph_captcha = StringField(validators=[Regexp(r'\w{4}', message='图形验证码错误')]) def validate_telephone(self, field): user = FrontUser.query.filter_by(telephone=field.data).first() if user: raise ValidationError('该手机号已被注册') def validate_sms_captcha(self, field): telephone = self.telephone.data sms_captcha = field.data xcache.set('13602219337', 'heboan') sms_captcha_mem = xcache.get(telephone) print('用户输入的验证码:{}'.format(sms_captcha)) print( '服务器存储的验证码:{}'.format(sms_captcha_mem)) if not sms_captcha_mem or sms_captcha_mem != sms_captcha: raise ValidationError(message='短信验证码错误') def validate_graph_captcha(self, field): graph_captcha = field.data #因为图形验证码存储的key和值都是一样的,所以我们只要判断key是否存在就行 if not xcache.get(graph_captcha.lower()): raise ValidationError(message='图形验证码错误')
然后就是注册的视图处理POST请求了, 编辑front.views.py
class SignUpViews(views.MethodView): def get(self): return render_template('front/front_signup.html') def post(self): signup_form = SignUpForm(request.form) if signup_form.validate(): telephone = signup_form.telephone.data username = signup_form.username.data password = signup_form.password1.data user = FrontUser(telephone=telephone, username=username, password=password) db.session.add(user) db.session.commit() return xjson.json_success('恭喜您,注册成功') else: return xjson.json_param_error(signup_form.get_error())
注册功能前端逻辑
前端我们通过ajax来请求,编辑front_signup.js
... //注册 $(function () { $('#submit-btn').click(function (event) { event.preventDefault(); var telephone_input = $("input[name='telephone']"); var sms_captcha_input = $("input[name='sms_captcha']"); var username_input = $("input[name='username']"); var password1_input = $("input[name='password1']"); var password2_input = $("input[name='password2']"); var graph_captcha_input = $("input[name='graph_captcha']") var telephone = telephone_input.val(); var sms_captcha = sms_captcha_input.val(); var username = username_input.val(); var password1 = password1_input.val(); var password2 = password2_input.val(); var graph_captcha = graph_captcha_input.val(); bbsajax.post({ 'url': '/signup/', 'data': { 'telephone': telephone, 'sms_captcha': sms_captcha, 'username': username, 'password1': password1, 'password2': password2, 'graph_captcha': graph_captcha }, 'success': function (data) { if (data['code'] === 200){ //注册成功跳转到首页 window.location = '/'; }else{ xtalert.alertInfo(data['message']); } }, 'fail': function (error) { xtalert.alertNetworkError(); } }); }) });
这样注册功能就OK,注册成功后会跳转到首页。
注册完成跳转回上一个页面
现在我们的需求是,用户直接进入注册页面注册,则注册成功后跳到首页,如果从本站的其他页面访问到注册页面注册,则注册成功后跳转到上一个页面。
那么我们可以在注册的视图函数中的get请求获取到referrer(上个页面,也就是从哪个页面跳过来的url)
#写一个检测referre的函数放到safeutils.py中,该文件放到utils下面 from utils import safeutils class SignUpViews(views.MethodView): def get(self): #获取上一个页面的url return_to = request.referrer #referrer不一定会存在,比如直接访问的登录页面 #并且它不等于登录页面的url #并且这个referre是个安全的url,防止恶意者去伪造它,被跳转到其它恶意的网站 if return_to and return_to !=request.url and safeutils.is_safe_url(return_to): #把这个url传入到模板中 return render_template('front/front_signup.html', return_to=return_to) return render_template('front/front_signup.html') ...
from urllib.parse import urlparse,urljoin from flask import request def is_safe_url(target): ref_url = urlparse(request.host_url) test_url = urlparse(urljoin(request.host_url, target)) return test_url.scheme in ('http', 'https') and \ ref_url.netloc == test_url.netloc
url传入到frony_signup.html,我在这个页面找个位置接收它
<span style="display:none;" id="return-to-span">{{ return_to }}</span>
然后我们的js就可以获取到这个值,编辑front_signup.js
每天进步一点,加油!