Flask项目流程(四)

本文为Flask项目流程第四部分,主要讲解了个人中心的设置,包括用户名和电话的修改,以及安全功能的实现,如重置密码、短信验证码功能。还介绍了钩子函数的应用和验证码确认路由,同时涵盖了数据库查询结果的降序排列方法。
摘要由CSDN通过智能技术生成

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值