登录状态显示修改密码的下拉菜单>>>点击进入修改密码的表单>>>提交替换密码给数据库 修改密码入口页面 flasky/app/templates/base.html
{% extends "bootstrap/base.html" %} {% block title %}Flasky{% endblock %} {% block head %} {{ super() }} <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> {% endblock %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="{{ url_for('main.index') }}">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="{{ url_for('main.index') }}">Home</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if current_user.is_authenticated %} ######################################## <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Account <b class="caret"></b></a> <ul class="dropdown-menu"> <li><a href="{{ url_for('auth.change_password') }}">Change Password</a></li> <li><a href="{{ url_for('auth.logout') }}">Log Out</a></li> </ul> </li> ###################################### {% else %} <li><a href="{{ url_for('auth.login') }}">Log In</a></li> {% endif %} </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">×</button> {{ message }} </div> {% endfor %} {% block page_content %}{% endblock %} </div> {% endblock %} {% block scripts %} {{ super() }} {{ moment.include_moment() }} {% endblock %}网页页面如下图: 修改密码的表单页面 flasky/app/templates/auth/change_password.html
{% extends "base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %}Flasky - Change Password{% endblock %} {% block page_content %} <div class="page-header"> <h1>Change Your Password</h1> </div> <div class="col-md-4"> {{ wtf.quick_form(form) }} </div> {% endblock %}网页页面如下图: 修改密码的表单 flasky/app/auth/forms.py
from flask_wtf import Form from wtforms import StringField, PasswordField, BooleanField, SubmitField from wtforms.validators import Required, Length, Email, Regexp, EqualTo from wtforms import ValidationError from ..models import User class LoginForm(Form): email = StringField('Email', validators=[Required(), Length(1, 64), Email()]) password = PasswordField('Password', validators=[Required()]) remember_me = BooleanField('Keep me logged in') submit = SubmitField('Log In') class RegistrationForm(Form): email = StringField('Email', validators=[Required(), Length(1, 64), Email()]) username = StringField('Username', validators=[ Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0, 'Usernames must have only letters, ' 'numbers, dots or underscores')]) password = PasswordField('Password', validators=[ Required(), EqualTo('password2', message='Passwords must match.')]) password2 = PasswordField('Confirm password', validators=[Required()]) submit = SubmitField('Register') def validate_email(self, field): if User.query.filter_by(email=field.data).first(): raise ValidationError('Email already registered.') def validate_username(self, field): if User.query.filter_by(username=field.data).first(): raise ValidationError('Username already in use.') ########################################################### class ChangePasswordForm(Form): old_password = PasswordField('Old password', validators=[Required()]) password = PasswordField('New password', validators=[ Required(), EqualTo('password2', message='Passwords must match')]) password2 = PasswordField('Confirm new password', validators=[Required()]) submit = SubmitField('Update Password') ###########################################################背后的控制器controller>>>views.py flasky/app/auth/views.py
from flask import render_template, redirect, request, url_for, flash from flask_login import login_user, logout_user, login_required, \ current_user from . import auth from .. import db from ..models import User from ..email import send_email from .forms import LoginForm, RegistrationForm, ChangePasswordForm @auth.before_app_request def before_request(): if current_user.is_authenticated \ and not current_user.confirmed \ and request.endpoint[:5] != 'auth.' \ and request.endpoint != 'static': return redirect(url_for('auth.unconfirmed')) @auth.route('/unconfirmed') def unconfirmed(): if current_user.is_anonymous or current_user.confirmed: return redirect(url_for('main.index')) return render_template('auth/unconfirmed.html') @auth.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() if user is not None and user.verify_password(form.password.data): login_user(user, form.remember_me.data) return redirect(request.args.get('next') or url_for('main.index')) flash('Invalid username or password.') return render_template('auth/login.html', form=form) @auth.route('/logout') @login_required def logout(): logout_user() flash('You have been logged out.') return redirect(url_for('main.index')) @auth.route('/register', methods=['GET', 'POST']) def register(): form = RegistrationForm() if form.validate_on_submit(): user = User(email=form.email.data, username=form.username.data, password=form.password.data) db.session.add(user) db.session.commit() token = user.generate_confirmation_token() send_email(user.email, 'Confirm Your Account', 'auth/email/confirm', user=user, token=token) flash('A confirmation email has been sent to you by email.') return redirect(url_for('auth.login')) return render_template('auth/register.html', form=form) @auth.route('/confirm/<token>') @login_required def confirm(token): if current_user.confirmed: return redirect(url_for('main.index')) if current_user.confirm(token): flash('You have confirmed your account. Thanks!') else: flash('The confirmation link is invalid or has expired.') return redirect(url_for('main.index')) @auth.route('/confirm') @login_required def resend_confirmation(): token = current_user.generate_confirmation_token() send_email(current_user.email, 'Confirm Your Account', 'auth/email/confirm', user=current_user, token=token) flash('A new confirmation email has been sent to you by email.') return redirect(url_for('main.index')) @auth.route('/change-password', methods=['GET', 'POST']) #更改密码路由 @login_required #要求已经登录 def change_password(): form = ChangePasswordForm() #创建form实例 if form.validate_on_submit(): #如果表格不为空,执行下列语句 if current_user.verify_password(form.old_password.data): #如果现在的用户旧密码验证正确,执行下列语句 current_user.password = form.password.data #表格中的密码赋值给用户中的密码 db.session.add(current_user) #加入数据库会话,自动提交到数据库 flash('Your password has been updated.') #出现flash消息 return redirect(url_for('main.index')) #重定向到主页 else: flash('Invalid password.') #否则显示flash消息显示旧密码不对 return render_template("auth/change_password.html", form=form) #表格为空直接刷新页面