flask登陆注册小Demo
flask登录注册小Demo
主要用到的知识点:
- flask配置文件,蓝图,闪现
- flask-session
- redis,DbUtils连接池
- wtforms表单验证模块
程序简单介绍:
登录通过wtforms做表单验证以及页面的渲染。获取登录数据后,在Dbutils提供的连接池中拿取一个连接,去数据库中查找,根据查找的结果返回相应的信息。如果用户名密码匹配成功,则通过flask-session把数据结构写入redis。
注册通过wtforms做表单验证以及页面的渲染,获取登录数据后,在Dbutils提供的连接池中拿取一个连接,去数据库中插入数据。
Demo下载地址:https://pan.baidu.com/s/1uqYWI5WUGDosgaEy16a5sg
提取码:pvbq
配置文件:
import pymysql from dbutils.pooled_db import PooledDB from redis import Redis from datetime import timedelta class Config: DEBUG = True SECRET_KEY = '6666661' SESSION_TYPE = 'redis' SESSION_REDIS = Redis(host='127.0.0.1', port=6379)
SESSION_REFRESH_EACH_REQUEST = True PERMANENT_SESSION_LIFETIME = timedelta(minutes=10) PYMYSQL_POOL = PooledDB( creator=pymysql, # 使用链接数据库的模块 maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数 mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建 maxcached=5, # 链接池中最多闲置的链接,0和None不限制 maxshared=3, # 链接池中最多共享的链接数量,0和None表示全部共享。 # PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1, # 所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。 blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错 maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."] ping=0, # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever # it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always host='127.0.0.1', port=3306, user='root', password='', database='userinfo1', charset='utf8' ) class DevelopmentConfig(Config): pass class ProductionConfig(Config): pass
SQLhelp,帮助我们通过pymysql操作数据库的类:
import pymysql from settings import Config class SQLHelp: @staticmethod def open(cursor): POOL = Config.PYMYSQL_POOL conn = POOL.connection() cursor = conn.cursor(cursor=cursor) return conn, cursor @staticmethod def close(conn, cursor): conn.commit() cursor.close() conn.close() @classmethod def fetch_one(cls, sql, args, cursor=pymysql.cursors.DictCursor): conn, cursor = cls.open(cursor) cursor.execute(sql, args) obj = cursor.fetchone() cls.close(conn, cursor) return obj @classmethod def fetch_all(cls, sql, args, cursor=pymysql.cursors.DictCursor): conn, cursor = cls.open(cursor) cursor.execute(sql, args) obj = cursor.fetchall() cls.close(conn, cursor) return obj @classmethod def insert_one(cls, sql, args, cursor=pymysql.cursors.DictCursor): conn, cursor = cls.open(cursor) res = cursor.execute(sql, args) cls.close(conn, cursor) return res
account.py:登录注册相关
from flask import Blueprint, render_template, session, redirect, request,flash from uuid import uuid4 account = Blueprint('ac',__name__) from ..utils.sql import SQLHelp from wtforms import Form from wtforms.fields import simple, core, html5 from wtforms import validators from wtforms import widgets class LoginForm(Form): user = simple.StringField( label='用户名', validators=[ validators.DataRequired(message='用户名不能为空') ], widget = widgets.TextInput(), render_kw={'class': 'form-control'} ) pwd = simple.PasswordField( label='密码', validators=[ validators.DataRequired(message='密码不能为空') ], widget=widgets.PasswordInput(), render_kw={'class':'form-control'} ) class RegisterForm(Form): user = simple.StringField( label='用户名', validators=[ validators.DataRequired(message='用户名不能为空') ], widget = widgets.TextInput(), render_kw={'class': 'form-control'} ) pwd = simple.PasswordField( label='密码', validators=[ validators.DataRequired(message='密码不能为空') ], widget=widgets.PasswordInput(), render_kw={'class':'form-control'} ) re_pwd = simple.PasswordField( label='密码', validators=[ validators.DataRequired(message='密码不能为空'), validators.EqualTo('pwd', message='两次密码输入不一致') ], widget=widgets.PasswordInput(), render_kw={'class': 'form-control'} ) @account.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': form = LoginForm() return render_template('login.html', form=form) form = LoginForm(formdata=request.form) if not form.validate(): return render_template('login.html', form=form) #print(form.data) # {'user': 'maomao', 'pwd': '123'} obj = SQLHelp.fetch_one('select * from users where name=%(user)s and pwd=%(pwd)s', form.data) if obj: uid = str(uuid4()) session['user_info'] = {'id': uid, 'name': obj['name']} flash('登录成功') return redirect('/index') return render_template('login.html', msg='用户名或密码错误!') @account.route('/register', methods=['GET','POST']) def register(): if request.method == 'GET': form = RegisterForm() return render_template('register.html', form=form) form = RegisterForm(formdata=request.form) if not form.validate(): return render_template('register.html', form=form) res = SQLHelp.insert_one('insert into users(name, pwd) values(%(user)s,%(pwd)s)', form.data) return redirect('/login')
主页:
from flask import Blueprint, render_template, session, redirect, request, get_flashed_messages home = Blueprint('home', __name__) @home.before_request def bf(): user_dict = session.get('user_info') if not user_dict: return redirect('/login') @home.route('/index') def index(): user = session.get('user_info')['name'] return render_template('index.html', name=user)
项目的init.py:
from flask import Flask from flask_session import Session from .views import account from .views import home def create_app(): app = Flask(__name__) app.config.from_object('settings.DevelopmentConfig') app.register_blueprint(account.account) app.register_blueprint(home.home) Session(app) return app
启动文件:
from flaskDemo import create_app app = create_app() if __name__ == '__main__': app.run()