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递归删除指定目录及其所有内容的方法
Jan 13 Python
python实现txt文件格式转换为arff格式
May 31 Python
Python画柱状统计图操作示例【基于matplotlib库】
Jul 04 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
Aug 22 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
Jan 15 Python
Python3实现的简单工资管理系统示例
Mar 12 Python
python numpy实现文件存取的示例代码
May 26 Python
python基于socket进行端口转发实现后门隐藏的示例
Jul 25 Python
Python3 翻转二叉树的实现
Sep 30 Python
Python Scrapy框架第一个入门程序示例
Feb 05 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
Jun 04 Python
python wsgiref源码解析
Feb 06 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
php email邮箱正则
2008/10/08 PHP
PHP 图片文件上传实现代码
2010/12/29 PHP
PHP与SQL注入攻击防范小技巧
2011/09/16 PHP
php+js iframe实现上传头像界面无跳转
2014/04/29 PHP
php解析base64数据生成图片的方法
2016/12/06 PHP
PHP设计模式之工厂方法设计模式实例分析
2018/04/25 PHP
用jquery来定位
2007/02/20 Javascript
jQuery的三种$()
2009/12/30 Javascript
FileUpload上传图片(图片不变形)
2010/08/05 Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
2011/03/03 Javascript
jQuery中 noConflict() 方法使用
2013/04/25 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
JavaScript实现同时调用多个函数的方法
2015/11/09 Javascript
Nodejs Express4.x开发框架随手笔记
2015/11/23 NodeJs
JavaScript的Backbone.js框架的一些使用建议整理
2016/02/14 Javascript
基于JavaScript实现在新的tab页打开url
2016/08/04 Javascript
javascript实现页面滚屏效果
2017/01/17 Javascript
基于jquery实现多级菜单效果
2017/07/25 jQuery
使用Vuex实现一个笔记应用的方法
2018/03/13 Javascript
Node.JS如何实现JWT原理
2020/09/18 Javascript
VUE-ElementUI 自定义Loading图操作
2020/11/11 Javascript
JS实现百度搜索框
2021/02/25 Javascript
python有证书的加密解密实现方法
2014/11/19 Python
Python处理Excel文件实例代码
2017/06/20 Python
Python使用APScheduler实现定时任务过程解析
2019/09/11 Python
python3中sys.argv的实例用法
2020/04/24 Python
Python中操作各种多媒体,视频、音频到图片的代码详解
2020/06/04 Python
Python实现简单猜数字游戏
2021/02/03 Python
应届大学生自荐信格式
2013/09/21 职场文书
物流业务员岗位职责
2014/02/08 职场文书
解放思想大讨论活动心得体会
2014/09/11 职场文书
运动会广播稿200字
2014/10/18 职场文书
公积金接收函格式
2015/01/30 职场文书
订货会邀请函
2015/01/31 职场文书
请假条应该怎么写?
2019/06/24 职场文书