Flask项目流程(四)
-
个人中心的设置
-
用户名和电话的修改
# forms.py
class EditProfile(FlaskForm):
username = StringField('用户名', validators=[DataRequired(message='请输入用户名'),
Length(0, 10, message='用户名不能超过10位')])
phone = StringField('电话', validators=[DataRequired(),
Regexp(regex='^\d{11}$', message='电话格式错误')])
submit = SubmitField('修改')
# views.py
@auth.route('/editprofile', methods=('GET', 'POST'))
@login_required
def editprofile():
form = EditProfile()
if form.validate_on_submit():
current_user.username = form.data['username']
current_user.phone = form.data['phone']
db.session.add(current_user)
db.session.commit()
flash('信息修改成功', category='success')
return redirect(url_for('auth.index'))
form.username.data = current_user.username
form.phone.data = current_user.phone
return render_template('auth/editprofile.html', form=form)
- 重置密码功能实现
# forms.py
class ResetPassword(FlaskForm):
password = PasswordField('旧密码', validators=[DataRequired()])
new_password = PasswordField('新密码', validators=[DataRequired()])
repassword = PasswordField('确认密码', validators=[DataRequired(),
EqualTo('new_password', message='两次密码不一致')])
submit = SubmitField('修改')
# views.py
@auth.route('/reset_password', methods=('GET', 'POST'))
@login_required
def reset_password():
form = ResetPassword()
if form.validate_on_submit():
if current_user.verify_password(form.data['password']):
current_user.password = form.data['new_password']
flash('密码重置成功,请重新登录', category='success')
db.session.add(current_user)
db.session.commit()
# 登出后重新登录
logout_user()
return redirect(url_for('auth.login'))
else:
flash('密码重置失败', category='error')
return redirect(url_for('auth.index'))
return render_template('auth/resetpassword.html', form=form)
- 短信验证码功能实现
# sms.py
import random
import string
from config import APIKEY
import requests
class YunPian():
def __init__(self, phone):
# 单条发送短信
self.url = 'https://sms.yunpian.com/v2/sms/single_send.json'
self.apikey = APIKEY
self.phone = phone
@staticmethod
def generate_code(count):
return ''.join(random.sample(string.digits, count))
def send_message(self, code):
response = requests.post(self.url, data={
'apikey': self.apikey,
'text': '【XXtest】您的验证码是code'.replace('code', str(code)),
'mobile': self.phone
})
return response
if __name__ == '__main__':
yunpian = YunPian(phone='XXX')
code = yunpian.generate_code(6)
yunpian.send_message(code)
- 钩子函数的应用
# views.py
# 全局运用钩子函数,不局限于蓝图
@auth.before_app_request
def unconfirmed():
form = ConfirmedForm()
if current_user.is_authenticated and not current_user.confirm_status \
and request.endpoint != 'auth.login' \
and request.endpoint != 'auth.register' \
and request.endpoint != 'auth.confirm' \
and request.endpoint != 'static':
form.phone.data = current_user.phone
# 查询出最近的code添加事件
old_code = Code.query.order_by(Code.add_time.desc()).first()
# 30秒间隔
from datetime import datetime, timedelta
inteval = timedelta(seconds=30)
can_resend = True if datetime.utcnow() - old_code.add_time >= inteval else False
print('can_resend:', can_resend)
return render_template('auth/unconfirmed.html', form=form, can_resend=can_resend)
# unconfirmed.html
{% extends 'bootstrap/base.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}验证页面{% endblock %}
{% block content %}
{% include 'flash.html' %}
<form action="{{ url_for('auth.confirm') }}">
{{ form.phone() }}
{% if can_resend %}
<input type="submit" value="发送验证码">
{% else %}
<span>请30秒后刷新页面在试!</span>
<input type="submit" value="发送验证码" disabled="disabled">
{% endif %}
</form>
{% endblock %}
- 验证码确认路由
# views.py
@auth.route('/confirm', methods=('GET', 'POST'))
def confirm():
form = ReConfirmedForm()
# print(request.args.get('phone'))
if form.validate_on_submit():
# 获取输入的验证码
code = form.data['code']
user_code = Code.query.filter_by(user_id=current_user.id).order_by(Code.add_time.desc()).first()
print(user_code)
print(user_code.verify_code(code))
if user_code.verify_code(code):
# 验证成功
current_user.confirm_status = True
db.session.add(current_user)
db.session.commit()
flash('验证成功', category='success')
return redirect(url_for('auth.index'))
else:
flash('验证失败', category='error')
return redirect(url_for('auth.index'))
phone = request.args.get('phone')
yunpian = YunPian(phone=phone)
code = yunpian.generate_code(6)
# 将验证码存入数据库中
verifycode = Code()
verifycode.code = code
verifycode.user_id = current_user.id
db.session.add(verifycode)
db.session.commit()
yunpian.send_message(code)
flash('验证码已发送至您的手机,请注意查收', category='success')
return render_template('auth/confirm.html', form=form)
- 数据库查询结果降序排列
Code.query.filter_by(user_id=current_user.id).order_by(Code.add_time.desc()).first()
old_code = Code.query.order_by(Code.add_time.desc()).first()