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扫描IP段查看指定端口是否开放的方法
Jun 09 Python
Python线程指南详细介绍
Jan 05 Python
python实现在IDLE中输入多行的方法
Apr 19 Python
Python 通配符删除文件的实例
Apr 24 Python
Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS浅析
May 08 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
Dec 10 Python
Python关于excel和shp的使用在matplotlib
Jan 03 Python
python实现各种插值法(数值分析)
Jul 30 Python
在PyCharm中实现添加快捷模块
Feb 12 Python
Python3如何判断三角形的类型
Apr 12 Python
python virtualenv虚拟环境配置与使用教程详解
Jul 13 Python
Python调用腾讯API实现人脸身份证比对功能
Apr 04 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 变量定义和变量替换的方法
2009/07/30 PHP
PHP 变量的定义方法
2010/01/26 PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
2017/04/01 PHP
php 算法之实现相对路径的实例
2017/10/17 PHP
JavaScript中的私有成员
2006/09/18 Javascript
利用JQuery和JS实现奇偶行背景颜色自定义效果
2012/11/19 Javascript
javascript实现信息的显示和隐藏如注册页面
2013/12/03 Javascript
js this函数调用无需再次抓获id,name或标签名
2014/03/03 Javascript
JQuery使用index方法获取Jquery对象数组下标的方法
2015/05/18 Javascript
javascript中不易分清的slice,splice和split三个函数
2016/03/29 Javascript
JS如何生成一个不重复的ID的函数
2016/12/25 Javascript
使用BootStrap进行轮播图的制作
2017/01/06 Javascript
原生JavaScript实现remove()和recover()功能示例
2018/07/24 Javascript
vue3+typeScript穿梭框的实现示例
2020/12/29 Vue.js
Python urllib、urllib2、httplib抓取网页代码实例
2015/05/09 Python
TensorFLow用Saver保存和恢复变量
2018/03/10 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
用pycharm开发django项目示例代码
2019/06/13 Python
浅析python内置模块collections
2019/11/15 Python
解决pytorch DataLoader num_workers出现的问题
2020/01/14 Python
通过实例解析Python return运行原理
2020/03/04 Python
Django用户身份验证完成示例代码
2020/04/03 Python
pytorch查看通道数 维数 尺寸大小方式
2020/05/26 Python
Scrapy+Selenium自动获取cookie爬取网易云音乐个人喜爱歌单
2021/02/01 Python
Joules官网:女士、男士和儿童服装和鞋类
2018/10/23 全球购物
六查六看剖析材料
2014/02/15 职场文书
《青海高原一株柳》教学反思
2014/04/25 职场文书
老人再婚离婚协议书范本
2014/10/27 职场文书
2014学生会工作总结报告
2014/12/02 职场文书
给校长的建议书范文
2015/09/14 职场文书
追悼会答谢词范文
2015/09/29 职场文书
2016党员读书思廉心得体会
2016/01/23 职场文书
详解Laravel框架的依赖注入功能
2021/05/27 PHP
PostgreSQL13基于流复制搭建后备服务器的方法
2022/01/18 PostgreSQL
Apache Hudi 加速传统的批处理模式
2022/04/24 Servers
解决Vmware虚拟机安装centos8报错“Section %Packages Does Not End With %End. Pane Is Dead”
2022/06/01 Servers