python使用Flask操作mysql实现登录功能


Posted in Python onMay 14, 2018

用到的一些知识点:Flask-SQLAlchemy、Flask-Login、Flask-WTF、PyMySQL

这里通过一个完整的登录实例来介绍,程序已经成功运行,在未登录时拦截了success.html页面跳转到登录页面,登录成功后才能访问success。

以下是项目的整体结构图:

python使用Flask操作mysql实现登录功能 

首先是配置信息,配置了数据库连接等基本的信息,config.py

DEBUG = True 
SQLALCHEMY_ECHO = False 
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:1011@localhost/rl_project?charset=utf8' 
SECRET_KEY = '*\xff\x93\xc8w\x13\x0e@3\xd6\x82\x0f\x84\x18\xe7\xd9\\|\x04e\xb9(\xfd\xc3'
common/_init_.py
# config=utf-8 
from flask_sqlalchemy import SQLAlchemy 
__all__ = ['db'] 
db = SQLAlchemy()

数据库配置类,common/data.py

# config=utf-8 
from sqlalchemy import create_engine 
from sqlalchemy.sql import text 
from config import SQLALCHEMY_DATABASE_URI, SQLALCHEMY_ECHO 
def db_query(sql, settings=None, echo=None): 
 if settings is None: 
  settings = SQLALCHEMY_DATABASE_URI 
 if echo is None: 
  echo = SQLALCHEMY_ECHO 
 return create_engine(settings, echo=echo).connect().execute(text(sql)).fetchall() 
def db_execute(sql, settings=None, echo=None): 
 if settings is None: 
  settings = SQLALCHEMY_DATABASE_URI 
 if echo is None: 
  echo = SQLALCHEMY_ECHO 
 return create_engine(settings, echo=echo).connect().execute(text(sql)).rowcount

SQLALCHEMY_DATABASE_URI用于连接数据的数据库。

SQLALCHEMY_ECHO如果设置成 True,SQLAlchemy 将会记录所有 发到标准输出(stderr)的语句,这对调试很有帮助。

当然,我们在setting中设置了基本的连接数据库信息,启动时加载app = create_app('../config.py'),所以这个类删掉也不会报错。

form/login_form.py

# config=utf-8 
from flask_wtf import FlaskForm as Form 
from wtforms import StringField, PasswordField 
from wtforms.validators import DataRequired 
class LoginForm(Form): 
 accountNumber = StringField('accountNumber', validators=[DataRequired('accountNumber is null')]) 
 password = PasswordField('password', validators=[DataRequired('password is null')])

使用Flask-WTF做登录的表单验证,这里简单做了账号密码不为空

如,当我们不填写密码时,点击登录:

python使用Flask操作mysql实现登录功能 

model/_init_.py

# config=utf-8 
from flask import Flask 
from flask_login import LoginManager 
from common import db 
login_manager = LoginManager() 
login_manager.login_view = "user.login" 
def create_app(config_filename=None): 
 app = Flask(__name__) 
 login_manager.init_app(app) 
 if config_filename is not None: 
  app.config.from_pyfile(config_filename) 
  configure_database(app) 
 return app 
def configure_database(app): 
 db.init_app(app)

其中,login_manager.login_view = "user.login" 指定了未登录时跳转的页面,即被拦截后统一跳到user/login这个路由下

model/user_model.py

# config=utf-8 
from flask_login import UserMixin 
from common import db 
class User(db.Model, UserMixin): 
 user_id = db.Column('id', db.Integer, primary_key=True) 
 accountNumber = db.Column(db.String(200), unique=True) 
 password = db.Column(db.String(50), unique=True) 
 name = db.Column(db.String(20), unique=True) 
 __tablename__ = 'tb_user' 
 def __init__(self, user_id=None, account_number=None, password=None, name="anonymous"): 
  self.user_id = user_id 
  self.accountNumber = account_number 
  self.password = password 
  self.name = name 
 def is_authenticated(self): 
  return True 
 def is_active(self): 
  return True 
 def is_anonymous(self): 
  return False 
 def get_id(self): 
  return unicode(self.user_id) 
 def __repr__(self): 
  return '<User %r>' % (self.accountNumber)

这里需要注意:

def get_id(self): 
  return unicode(self.user_id)

该方法不可缺少,否则会报:NotImplementedError: No `id` attribute - override `get_id`错误。

get_id()

返回一个能唯一识别用户的,并能用于从 user_loader 回调中 加载用户的 unicode 。注意着 必须 是一个 unicode ——如果 ID 原本是 一个 int 或其它类型,你需要把它转换为 unicode 。

is_authenticated()

当用户通过验证时,也即提供有效证明时返回 True

is_active()

如果这是一个通过验证、已激活、未被停用的账户返回 True 。

is_anonymous()

如果是一个匿名用户,返回 True 。

login.py

#encoding:utf-8 
#!/usr/bin/env python 
from flask import render_template, request, redirect, Flask, Blueprint 
from flask_login import login_user, login_required 
from model.user_model import User 
from model import login_manager 
from form.login_form import LoginForm 
userRoute = Blueprint('user', __name__, url_prefix='/user', template_folder='templates', static_folder='static') 
@login_manager.user_loader 
def load_user(user_id): 
 return User.query.get(int(user_id)) 
@userRoute.before_request 
def before_request(): 
 pass 
@userRoute.route('/success') 
@login_required 
def index(): 
 return render_template('success.html') 
@userRoute.route('/login', methods=['GET', 'POST']) 
def login(): 
 form = LoginForm() 
 if request.method == 'POST': 
  if not form.validate_on_submit(): 
   print form.errors 
   return render_template('login.html', form=form) 
  user = User.query.filter(User.accountNumber == form.accountNumber.data, 
         User.password == form.password.data).first() 
  if user: 
   login_user(user) 
   return render_template('success.html') 
 return render_template('login.html', form=form)

其中,要实现一个load_user()回调方法,这个回调用于从会话中存储的用户 ID 重新加载用户对象,id存在则返回对应的用户对象,不存在则返回none。

有些操作是需要用户登录的,有些操作则无需用户登录,这里使用到了@login_required,在每一个需要登录才能访问的路由方法上加@login_required即可。

启动类,runserver.py

# config=utf-8 
from login import userRoute 
from model import create_app 
DEFAULT_MODULES = [userRoute] 
app = create_app('../config.py') 
for module in DEFAULT_MODULES: 
 app.register_blueprint(module) 
@app.before_request 
def before_request(): 
 pass 
if __name__ == '__main__': 
 app.run(debug=True)
DEFAULT_MODULES = [userRoute]是将userRoute蓝图注册入app,才能启动login中的userRoute路由,我们在login.py中使用了蓝图:userRoute = Blueprint('user', __name__, url_prefix='/user', template_folder='templates', static_folder='static')
@app.before_request 
def before_request(): 
 pass

这是一个全局的方法,在请求开始之前被调用,在某些场景下做一些提示或者特殊处理,当然这里没用上,直接pass,这个方法去掉对项目没有影响。

基本样式模版,base.html

<!DOCTYPE html> 
<html lang="cn"> 
<head> 
 <meta charset="UTF-8"> 
 <title>{% block title %}{% endblock %}</title> 
 <script src="{{ url_for('static', filename='jquery1.42.min.js') }}"></script> 
 {% block head %}{% endblock %} 
</head> 
<body> 
{% block content %}{% endblock %} 
</body> 
</html>

登录前台页面,login.html

{% extends "base.html" %} 
{% block title %}python flask user page{% endblock %} 
{% block head %} 
 <style type="text/css"></style> 
{% endblock %} 
{% block content %} 
 <form action="{{ url_for('user.login') }}" method="post"> 
  {% if form.errors %} 
   <ul> 
    {% for name, errors in form.errors.items() %} 
     {% for error in errors %} 
      <li>{{ error }}</li> 
     {% endfor %} 
    {% endfor %} 
   </ul> 
  {% endif %} 
  账号:{{ form.accountNumber(size=20) }}<label>{{ form.accountNumber.errors[0] }}</label><br/> 
  密码:<input name="password" type="password"/><br/> 
  {{ form.hidden_tag() }} 
  <button type="submit">登录</button> 
 </form> 
{% endblock %}

到此,一个Flask实现简单登录功能就做完了。

总结

以上所述是小编给大家介绍的python使用Flask操作mysql实现登录功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python Django使用forms来实现评论功能
Aug 17 Python
python3 发送任意文件邮件的实例
Jan 23 Python
python微信跳一跳系列之自动计算跳一跳距离
Feb 26 Python
分享一下Python数据分析常用的8款工具
Apr 29 Python
python自动化生成IOS的图标
Nov 13 Python
Python读取指定日期邮件的实例
Feb 01 Python
详解Python给照片换底色(蓝底换红底)
Mar 22 Python
解决python3 安装不了PIL的问题
Aug 16 Python
python 实现矩阵按对角线打印
Nov 29 Python
python获取系统内存占用信息的实例方法
Jul 17 Python
在Python3.74+PyCharm2020.1 x64中安装使用Kivy的详细教程
Aug 07 Python
python多线程和多进程关系详解
Dec 14 Python
查看Django和flask版本的方法
May 14 #Python
Python处理中文标点符号大集合
May 14 #Python
python numpy格式化打印的实例
May 14 #Python
Python常见字典内建函数用法示例
May 14 #Python
python:print格式化输出到文件的实例
May 14 #Python
查看django版本的方法分享
May 14 #Python
django 修改server端口号的方法
May 14 #Python
You might like
dede3.1分页文字采集过滤规则详说(图文教程)
2007/04/03 PHP
PHP中文字符串截断无乱码解决方法
2016/10/10 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
Jquery 学习笔记(一)
2009/10/13 Javascript
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
JavaScript中的apply和call函数详解
2014/07/20 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
javascript实现的简单的表单验证
2015/07/10 Javascript
正则表达式优化JSON字符串的技巧
2015/12/24 Javascript
详解vue-cli 脚手架项目-package.json
2017/07/04 Javascript
详解React-Native全球化多语言切换工具库react-native-i18n
2017/11/03 Javascript
详解Nodejs内存治理
2018/05/13 NodeJs
Vue.js实现的表格增加删除demo示例
2018/05/22 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
2018/08/06 Javascript
了解在JavaScript中将值转换为字符串的5种方法
2019/06/06 Javascript
详解vue微信网页授权最终解决方案
2019/06/16 Javascript
react koa rematch 如何打造一套服务端渲染架子
2019/06/26 Javascript
jquery轻量级数字动画插件countUp.js使用详解
2019/10/17 jQuery
vue实现编辑器键盘抬起时内容跟随光标距顶位置向上滚动效果
2020/05/28 Javascript
javascript实现左右缓动动画函数
2020/11/25 Javascript
mustache.js实现首页元件动态渲染的示例代码
2020/12/28 Javascript
Windows下的Python 3.6.1的下载与安装图文详解(适合32位和64位)
2018/02/21 Python
获取django框架orm query执行的sql语句实现方法分析
2019/06/20 Python
Python3 字典dictionary入门基础附实例
2020/02/10 Python
css3 transform导致子元素固定定位变成绝对定位的方法
2020/03/06 HTML / CSS
H5页面适配iPhoneX(就是那么简单)
2019/12/02 HTML / CSS
英国乐购杂货:Tesco Groceries
2018/11/29 全球购物
财务部岗位职责
2013/11/19 职场文书
个人委托书范本
2014/04/02 职场文书
小学生作文评语
2014/04/18 职场文书
公开承诺书格式
2014/05/21 职场文书
企业领导对照检查材料
2014/08/20 职场文书
2014年科室工作总结范文
2014/12/19 职场文书
学校2016年圣诞节活动总结
2016/03/31 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
详解php中流行的rpc框架
2021/05/29 PHP