【Python 实战基础】Flask + MySQL 如何实现用户注册,登录和登出

目录

一、实战场景

二、主要知识点

三、菜鸟实战

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

2、设置配置文件

3、蓝图初始化

4、编写注册表单

5、提交注册表单

6、用户模型

7、模型基类

8、表单验证

9、代码主要目录结构

四、运行结果

1、注册和验证

2、注册成功登录 

3、登录 


一、实战场景

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、注册和验证

2、注册成功登录 

3、登录 

菜鸟实战,持续学习!

  • 36
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 34
    评论
Python中使用FlaskMySQL可以很方便地实现用户注册登录登出功能。 首先,我们需要安装Flask和PyMySQL库,并导入所需的模块。 ```python from flask import Flask, render_template, request, redirect, session import pymysql ``` 接下来,我们需要创建一个Flask应用程序,并配置数据库连接。 ```python app = Flask(__name__) app.secret_key = 'your_secret_key' # 设置session密钥 conn = pymysql.connect( host='your_host', user='your_username', password='your_password', db='your_database' ) ``` 然后,我们可以定义一些路由来处理用户注册登录的请求。 ```python @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] # 在这里将用户信息插入到数据库中 cursor = conn.cursor() sql = "INSERT INTO users (username, password) VALUES (%s, %s)" cursor.execute(sql, (username, password)) conn.commit() cursor.close() return redirect('/login') return render_template('register.html') @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] # 在这里从数据库中验证用户信息 cursor = conn.cursor() sql = "SELECT * FROM users WHERE username = %s AND password = %s" cursor.execute(sql, (username, password)) user = cursor.fetchone() cursor.close() if user: session['username'] = username return redirect('/') else: return render_template('login.html', message='用户名或密码错误') return render_template('login.html') @app.route('/logout') def logout(): session.pop('username', None) return redirect('/login') ``` 最后,我们可以定义一个主页路由来展示当前登录状态。 ```python @app.route('/') def home(): if 'username' in session: return '当前用户:' + session['username'] + '<br><a href="/logout">登出</a>' else: return '未登录<br><a href="/login">登录</a>' ``` 你还需要创建一个注册页面和登录页面的模板文件。 ```html <!-- register.html --> <form method="POST" action="/register"> <input type="text" name="username" placeholder="用户名"><br> <input type="password" name="password" placeholder="密码"><br> <button type="submit">注册</button> </form> ``` ```html <!-- login.html --> <form method="POST" action="/login"> <input type="text" name="username" placeholder="用户名"><br> <input type="password" name="password" placeholder="密码"><br> <button type="submit">登录</button> </form> <p>{{ message }}</p> ``` 最后,我们需要运行Flask应用程序。 ```python if __name__ == '__main__': app.run() ``` 现在,你可以通过访问http://localhost:5000/register来注册新用户,并访问http://localhost:5000/login来登录登出功能可以通过访问http://localhost:5000/logout来实现。主页会展示当前登录状态。 以上就是使用PythonFlaskMySQL实现用户注册登录登出的简单示例。希望能帮到你!
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟实战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值