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 相关文章推荐
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
Sep 26 Python
Python编程给numpy矩阵添加一列方法示例
Dec 04 Python
pycharm的console输入实现换行的方法
Jan 16 Python
Python3爬楼梯算法示例
Mar 04 Python
Python合并同一个文件夹下所有PDF文件的方法
Mar 11 Python
python之pyqt5通过按钮改变Label的背景颜色方法
Jun 13 Python
关于Python 的简单栅格图像边界提取方法
Jul 05 Python
python 实现在一张图中绘制一个小的子图方法
Jul 07 Python
django数据关系一对多、多对多模型、自关联的建立
Jul 24 Python
python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例
Mar 19 Python
python向企业微信发送文字和图片消息的示例
Sep 28 Python
解决pycharm不能自动保存在远程linux中的问题
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
ASP和PHP都是可以删除自身的
2007/04/09 PHP
几款免费开源的不用数据库的php的cms
2010/12/19 PHP
一个简单且很好用的php分页类
2013/10/26 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
不错的一个日期输入 动态
2006/11/06 Javascript
JS简单操作select和dropdownlist实例
2014/11/26 Javascript
jQuery超赞的评分插件(8款)
2015/08/20 Javascript
基于jQuery实现复选框是否选中进行答题提示
2015/12/10 Javascript
深入理解ECMAScript的几个关键语句
2016/06/01 Javascript
详解AngularJs ui-router 路由的简单介绍
2017/04/26 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
webpack分离css单独打包的方法
2018/06/12 Javascript
Webpack devServer中的 proxy 实现跨域的解决
2018/06/15 Javascript
vue 项目接口管理的实现
2019/01/17 Javascript
vue中添加与删除关键字搜索功能
2019/10/12 Javascript
[15:09]DOTA2国际邀请赛采访专栏:Loda
2013/08/06 DOTA
python网络编程学习笔记(九):数据库客户端 DB-API
2014/06/09 Python
Python lxml模块安装教程
2015/06/02 Python
Python pass详细介绍及实例代码
2016/11/24 Python
python2.7 json 转换日期的处理的示例
2018/03/07 Python
详解Python 解压缩文件
2019/04/09 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
2019/09/20 Python
python实现在内存中读写str和二进制数据代码
2020/04/24 Python
全方位了解CSS3的Regions扩展
2015/08/07 HTML / CSS
css3 transform 3d 使用css3创建动态3d立方体(html5实践)
2013/01/06 HTML / CSS
纽约家具、家居装饰和地毯店:ABC Carpet & Home
2017/06/21 全球购物
CSS实现fullpage.js全屏滚动效果的示例代码
2021/03/24 HTML / CSS
《两个铁球同时着地》教学反思
2014/02/13 职场文书
行政助理工作职责范本
2014/03/04 职场文书
蓝颜请假条
2014/04/11 职场文书
校园安全演讲稿
2014/05/09 职场文书
法律意见书范文
2015/06/04 职场文书
小学班主任工作经验交流材料
2015/11/02 职场文书
简短的人生哲理(38句)
2019/08/13 职场文书
导游词之杭州西湖
2019/09/19 职场文书
Mysql实现简易版搜索引擎的示例代码
2021/08/30 MySQL