Flask + MySQL如何实现用户注册,登录和登出的项目实践

作者:菜鸟实战 时间:2024-01-21 17:02:33 

一、实战场景

Flask 框架实现用户的注册,登录和登出。

二、主要知识点

  • flask_login 插件使用

  • SQLAlchemy 基础操作

  • 用户基础类设计

  • Flask 读取配置文件

  • 蓝图注册与使用

  • wtforms 表单提交数据

  • wtforms 表单验证

  • Bootstrap 集成

  • Jinjia2 模版继承

 涉及的知识点和细节很多,我下面就直接贴出注册部分的核心代码

三、菜鸟实战

马上安排!

1、应用初始化 MySQL 和 flask_login 模块

'''
Author: 菜鸟实战
Description: 创建应用程序,并注册相关蓝图
'''

from flask import Flask
from base.base_model import db
from flask_login import LoginManager

# 登录插件
login_manager = LoginManager()

def register_auth_blueprint(app):
   # 注册蓝图
   from app.auth import auth_bp
   app.register_blueprint(auth_bp)

def create_app(config=None):
   # 创建应用
   app = Flask(__name__)

# 加载配置
   app.config.from_object('config')

# 注册 SQLAlchemy
   db.init_app(app)
   #
   # 注册 login 模块
   login_manager.init_app(app)

# 未登录时候的默认跳转页面
   login_manager.login_view = 'auth.login'
   # # login_manager.login_message = '请先登录或注册'

register_auth_blueprint(app)

if config is not None:
       if isinstance(config, dict):
           app.config.update(config)
       elif config.endswith('.py'):
           app.config.from_pyfile(config)

return app

app = create_app()

with app.app_context():
   db.create_all()

if __name__ == '__main__':
   # 如果要使用 vscode 调试,需要将 debug 设置为 False,否则无法命中请求断点
   app.run(host='0.0.0.0', debug=True)

2、设置配置文件


APP_NAME = "north"

SECRET_KEY = "fNqh2TNw3l0Dj8ZCMQyQh7m1YvWVSgDx"

DEBUG = True

SQLALCHEMY_DATABASE_URI = 'mysql://username:password@ip:3306/dbname'

# 设置sqlalchemy自动更跟踪数据库
SQLALCHEMY_TRACK_MODIFICATIONS = True

# 查询时会显示原始SQL语句
SQLALCHEMY_ECHO = True

3、蓝图初始化

'''
Author: 菜鸟实战
'''

from flask import Blueprint

auth_bp = Blueprint(
   'auth',
   __name__,
)

from app.auth.user import user, auth

4、编写注册表单

<main class="form-signin w-100 m-auto">
<form action="{{ url_for('auth.register') }}" method="post">
   <img class="mb-4" src="{{ url_for('static', filename="3rd/images/bootstrap-logo.svg") }} " alt="" width="72" height="57">
   <h1 class="h3 mb-3 fw-normal">注册信息</h1>

<div class="form-floating">
     <input class="form-control"
            id="nickname" name="nickname"
             value="{{ form.data['nickname'] | default('',true) }}"
             placeholder="昵称">
     <label for="floatingInput">昵称</label>
   </div>
   <div class="form-floating">
     <input type="email" class="form-control"
            id="email" name="email"
             value="{{ form.data['email'] | default('',true) }}"
             placeholder="Email">
     <label for="floatingInput">邮箱</label>
   </div>
   <div class="form-floating">
     <input type="password" class="form-control"
             id="password" name="password"
             value="{{ form.data['password'] | default('',true) }}"
             placeholder="Password">
     <label for="floatingPassword">密码</label>
   </div>
   <div class="form-floating">
     <input type="password" class="form-control"
             id="confirm_password" name="confirm_password"
             value="{{ form.data['confirm_password'] | default('',true) }}"
             placeholder="Confirm Password">
     <label for="floatingPassword">确认密码</label>
   </div>
       {% if form and form.errors %}
           {% for key, error in form.errors.items() %}
               <div class="alert alert-warning" role="alert">{{ key }} : {{ error }}</div>
           {% endfor %}
       {% endif %}

<button class="w-100 btn btn-lg btn-primary" type="submit">注册</button>
   <p class="mt-5 mb-3 text-muted">菜鸟实战 &copy; 2017–2022</p>
 </form>
</main>

5、提交注册表单

@auth_bp.route("/register", methods=['POST', 'GET'])
def register():
   # 注册逻辑
   form = RegisterForm(request.form)

# 检查
   if request.method == 'POST' and form.validate():
       # 执行正确逻辑
       user = User()
       user.set_attrs(form.data)

user.name = user.nickname
       user.token = user.generate_token()

db.session.add(user)
       db.session.commit()

# 执行登录
       login_user(user, False)

return redirect(url_for('auth.home'))

return render_template("auth/register.html", form=form)

6、用户模型

'''
Author: 菜鸟实战
'''
import random

from sqlalchemy import Column, ForeignKey, func
from sqlalchemy import String, Unicode, DateTime, Boolean
from sqlalchemy import TIMESTAMP, Integer, Float
from flask_login import login_user, login_required, logout_user, current_user, UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

from common.helpers.str_helper import random_string
from north import login_manager

from  base.base_model import BaseModel

class User(BaseModel, UserMixin):
   # UserMixin 继承属性
   __tablename__ = 'users'

# 表基础值
   phone_number = Column(String(16), unique=True)
   email = Column(String(64), unique=True, nullable=False)
   token = Column(String(64))
   password = Column('password', String(100))
   status = Column(Integer, default=1)
   type = Column(Integer, default=1)

# 定义一个对象属性,对应表中的 password 字段
   _password = Column('password', String(100))

@property
   def password(self):
       # 定义属性,使用对象属性赋值
       return self._password

@password.setter
   def password(self, raw):
       # 属性赋值
       self._password = generate_password_hash(raw)

def check_password(self, raw):
       # 检查密码
       if not self._password:
           return False
       return check_password_hash(self._password, raw)

def generate_token(self, expiration=60000):
       # 生成 token
       return random_string(32)

@login_manager.user_loader
def get_user(uid):
   # 必须, login 插件制定方法
   return User.query.get(int(uid))

7、模型基类

'''
Author: 菜鸟实战
'''

import pymysql
import datetime

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, SmallInteger
from sqlalchemy import String, Unicode, DateTime, Boolean

# 初始化数据库类型
pymysql.install_as_MySQLdb()
db = SQLAlchemy()

# 模型基础类
class BaseModel(db.Model):
   __abstract__ = True

id = Column(Integer, primary_key=True)
   name = Column(String(32), nullable=False)
   nickname = Column(String(32), nullable=False)
   is_enable = Column(SmallInteger, default=1, nullable=False)
   created_at = db.Column(db.DateTime, default=datetime.datetime.now)
   updated_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)
   deleted_at = db.Column(db.DateTime)

def __init__(self):
       pass

# 字典赋值, 场景: 表单提交
   def set_attrs(self, attrs):
       for key, value in attrs.items():
           if hasattr(self, key) and key != 'id':
               setattr(self, key, value)

8、表单验证

'''
Author: 菜鸟实战
Description: 注册表单
'''
from wtforms import StringField, PasswordField, Form, validators
# from wtforms.validators import Length, Email, \
#     ValidationError, EqualTo
from app.auth.user.user_model import User

class RegisterForm(Form):
   nickname = StringField('昵称',
       validators = [
           validators.DataRequired(),
           validators.Length(2, 32)
           #   validators.Email(message='电子邮箱不符合规范')
       ])
   email = StringField('电子邮件',
       validators = [
           validators.DataRequired(),
           validators.Length(10, 50)

#   validators.Email(message='电子邮箱不符合规范')
       ])
   password = PasswordField('密码', [
       validators.DataRequired(),
       validators.EqualTo('confirm_password', message='密码需要一致')
   ])
   confirm_password = PasswordField('Repeat Password', [
       validators.DataRequired(),

])

def validate_email(self, field):
       # 自定义验证,命名对应
       if User.query.filter_by(email=field.data).first():
           raise validators.ValidationError('邮件已被注册')

def validate_nickname(self, field):
       if User.query.filter_by(nickname=field.data).first():
           raise validators.ValidationError('昵称已存在')

9、代码主要目录结构

├── app
│   ├── __init__.py
│   ├── auth
│   │   ├── __init__.py
│   │   └── user
│   └── tools
│       ├── __init__.py
│       └── db_tools.py
├── base
│   ├── __init__.py
│   ├── base_blueprint.py
│   ├── base_form.py
│   └── base_model.py
├── common
│   ├── __init__.py
│   └── helpers
│       ├── __init__.py
│       └── str_helper.py
├── config.py 

├── north.py 

四、运行结果

1、注册和验证

Flask + MySQL如何实现用户注册,登录和登出的项目实践

2、注册成功登录 

Flask + MySQL如何实现用户注册,登录和登出的项目实践

3、登录 

Flask + MySQL如何实现用户注册,登录和登出的项目实践

来源:https://blog.csdn.net/qq_39816613/article/details/125100662

标签:Flask,MySQL,注册,登录,登出
0
投稿

猜你喜欢

  • python实现图像检索的三种(直方图/OpenCV/哈希法)

    2021-08-11 17:15:08
  • 怎样在SQL Server 2005中用证书加密数据

    2009-01-04 14:11:00
  • python修改FTP服务器上的文件名

    2022-11-08 00:22:15
  • MYSQL不能从远程连接的一个解决方法(s not allowed to connect to this MySQL server)

    2024-01-19 02:57:34
  • node命令行服务器(http-server)和跨域的实现

    2021-03-10 05:00:09
  • js实现网页加载loading的显示

    2007-11-06 12:11:00
  • python 实现dcmtk关联pacs功能推送下拉影像(推荐)

    2021-10-15 15:58:43
  • Python list与NumPy array 区分详解

    2021-08-25 04:12:37
  • Python Flask框架实现Proteus仿真Arduino与网页数据交互

    2022-01-18 08:43:16
  • python爬取代理IP并进行有效的IP测试实现

    2021-05-08 15:31:38
  • Python封装解构以及丢弃变量

    2022-08-10 07:55:58
  • 使用numpy.mean() 计算矩阵均值方式

    2021-12-17 03:55:53
  • 网页特效文字之—银箔字

    2013-08-07 00:21:39
  • 微信 java 实现js-sdk 图片上传下载完整流程

    2024-04-29 14:08:03
  • Vue.js结合SortableJS实现树形数据拖拽

    2024-04-30 10:38:06
  • 带你了解HDFS的Namenode 高可用机制

    2023-12-08 10:20:45
  • python的id()函数解密过程

    2023-03-04 00:17:52
  • Python 变量的创建过程详解

    2022-04-20 03:01:17
  • 短视频(douyin)去水印工具的实现代码

    2024-04-29 13:40:15
  • 微信 小程序Demo导入详细介绍

    2023-01-13 22:16:19
  • asp之家 网络编程 m.aspxhome.com