Flask -- 使用数据库(Sqlite3)、用户注册、登录注销、修改密码
# 使用sqlite数据库 import sqlite3
from contextlib import closing app.config.update( DATABASE = 'my.db', #相对于文件所在目录 DEBUG=True, ) def connect_db(): return sqlite3.connect(app.config['DATABASE']) def init_db(): with closing(connect_db()) as db: with app.open_resource('schema.sql', 'r') as f: db.cursor().executescript(f.read()) db.commit() def get_db(): db = connect_db() cur = db.cursor() return db, cur
# 用户注册
from wtforms import Form, TextField, PasswordField, BooleanField, validators
from passlib.hash import sha256_crypt
import gc
class RegistrationForm(Form): 使用flask-WTF表单系统,可以方便地使用逻辑(pip install flask-WTF) username = TextField('Username', [validators.Length(min=4, max=20)]) email = TextField('Email', [validators.Length(min=6, max=50)]) password = PasswordField('Password', [validators.Required(), validators.EqualTo('confirm', message='Passwords must match.')]) confirm = PasswordField('Password Again') accept_tos = BooleanField("<small>I accept it</small>", [validators.Required()]) @app.route('/register/', methods=['POST', 'GET']) def register(): try: form = RegistrationForm(request.form) if request.method == 'POST' and form.validate(): username = form.username.data email = form.email.data password = sha256_crypt.encrypt(str(form.password.data)) #对密码加密,生成一个hash值[每次调用生成不同的hash](pip install passlib) db, cur = get_db() x = cur.execute( 'SELECT * FROM users WHERE username = ?', [username]) if x.fetchall(): flash("That username is already taken, please choose another") return render_template('register.html', form=form) else: cur.execute("INSERT INTO users (username, password, email) VALUES(?,?,?)", [ username, password, email]) db.commit() flash("Thanks for registering!") cur.close() db.close() gc.collect() # collect garbage session['logged_in'] = True session['username'] = username return redirect(url_for('dashboard')) return render_template('register.html', form=form) except Exception as e: return str(e)
#register.html <div class="container" style> <h4>Welcome to register</h4> <br /> {% from '_formhelpers.html' import render_field %} <form action="" method="post"> {{ render_field(form.username) }} {{ render_field(form.email) }} {{ render_field(form.password) }} {{ render_field(form.confirm) }} {{ render_field(form.accept_tos) }} <p><input type="submit" value="Register" /></p> </form> {% if error %} <p class="error"><strong>Error: </strong>{{ error }}</p> {% endif %} </div>
# _formhelper.html {% macro render_field(field) %} 宏逻辑,相当于一个函数 <dt>{{ field.label }}</dt> <dd>{{ field(**kwargs) | safe }} {% if field.errors %} <ul class="errors"> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} <dd> {% endmacro %}
#用户登录
@app.route('/login/', methods=['POST', 'GET']) def login(): try: error = None if request.method == 'POST': username = request.form['username'] password = request.form['password'] db, cur = get_db() passwd_hash_tuple = cur.execute( 'SELECT password FROM users WHERE username=?', [username]).fetchone() # return a tuple if not passwd_hash_tuple: error = 'Invalid username' elif not sha256_crypt.verify(password, passwd_hash_tuple[0]): error = 'Invalid password' else: flash('Hey %s, you are in' % username) session['logged_in'] = True session['username'] = username return redirect(url_for('dashboard')) gc.collect() return render_template('login.html', error=error) except Exception as e: return str(e)
# login.html
<div class="container"> {% if error %} <p class="alert alert-danger">{{ error }}</p> {% endif %} <h4>Please Login</h4> <form method="post" action="" class="form-inline"> <input type="text" class="form-control" placeholder="username" name="username" value="{{ request.form.username }}" /> <input type="password" class="form-control" placeholder="password" name="password" value="{{ request.form.password }}" /> <input type="submit" class="btn btn-default" value="Login" /> </form> </div>
# 用户退出 @app.route('/logout/') @login_required def logout(): session.pop('logged_in', None) flash("You have logged out") return redirect(url_for('dashboard'))
KEEP LEARNING!