SQLALchemy在Falsk中的运用

本次内容解决的主要问题是Flask中运用SQLALchemy在进行蓝图模块化处理时遇到的问题在用蓝图模块进行操作路由映射方法的时候,发现模块化的路由不能够直接进行实例化db操作数据库

本次程序的全部结构:

 SQLALchemy的主要运用就是对象关系映射ORM模式操作数据库

1.建立mysql和app的连接

在config.py中加入几项数据库的配置:

# 创建数据库sqlalchemy工具链接
SQLALCHEMY_DATABASE_URI ="mysql+pymysql://root:Root123@127.0.0.1:3306/hj"
# 是否追踪数据库修改,一般不开启, 会影响性能
SQLALCHEMY_TRACK_MODIFICATIONS = False
# # 是否显示底层执行的SQL语句
SQLALCHEMY_ECHO = True
# 禁止自动提交数据处理
SQLALCHEMY_COMMIT_ON_TEARDOWN = False

2.完成app和数据的关联,并且生成一个可以操作app数据库的SQLALchemy的实例对象db

完整app/__init__.py代码:

from flask import Flask, current_app, url_for, request, redirect, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)

"""上下文处理机制解决方法"""
ctx = app.app_context()
ctx.push()
"""------------------"""


app.config.from_object('config')
db = SQLAlchemy(app)

from app import models,views

注意:这里解决的一个位置的问题:RuntimeError: Working outside of application context

这里操作要获取得flask和对象app(即不启动服务器),但是获取不到app对象,原因是因为flask上下文机制,具体问题解释请查看https://blog.csdn.net/weixin_36672636/article/details/104612498/

3.创建数据表模块

#app/models.py

from app import db
#db是在app/__init__.py生成关联后的SQLALchemy实例

class User(db.Model):
    # 定义表名
    __tablename__ = 'users'
    # 定义字段
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(64))
    password = db.Column(db.String(64))
    phone = db.Column(db.String(64))

4.创建表db_create.py,表结构完成后执行db_create.py就可以完成表的创建

#app/db_create.py

from app import db, ctx

db.create_all()

ctx.pop()

5.业务流程操作数据库,并且使用蓝图对路由进行进行模块化处理

#app/user.py

from flask import Blueprint, render_template, request,current_app
from .models import User
from app import db

user = Blueprint('user', __name__)

@user.route('/login', methods=['GET', 'POST'])
def login():
    if request.method =='GET':
        return render_template('login.html')
    user_name = request.form.get('name')
    user_password = request.form.get('password')
    user_phone = request.form.get('phone')
    user = User()
    user.name = user_name
    user.password = user_password
    user.phone = user_phone
    db.session.add(user)
    db.session.commit()
    return render_template('success.html')

#app/admin.py

from flask import Blueprint, render_template, jsonify, request,current_app
from .common import random_num
from .redis_con import redis_store
from .models import User

admin = Blueprint('admin', __name__)

@admin.route('/')
def index():
    if request.method == 'GET':
        return render_template('index.html')

@admin.route('/valid_code')
def valid_vode():
    # 获取数据
    phone = request.args.get('phone')
    print(phone)

    try:
        # 生成四位随机数字字母作为验证码
        code = random_num()
        # 将验证码保存到redis中,第一个参数是key,第二个参数是value,第三个参数表示60秒后过期
        redis_store.set('{}'.format(phone), '{}'.format(code), 60)
        # 这里用输出验证码来代替短信发送验证码
        print(code)
        return jsonify(status="成功", msg="验证码发送成功")
    except Exception as e:
        return jsonify(status='失败', msg="验证码发送失败")

@admin.route('/user_check')
def admin_check():
    if request.method == 'GET':
        users = User.query.all()
        return render_template('user_check.html', users=users)

因为我个人的操作我这里添加了一个redis操作的部分内容,可以将@admin.route('/valid_code')此路由删除

#app/templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <!-- 引入jquery -->
    <script src="/static/js/jquery-3.6.5.js"></script>
</head>
<body>
<form action="/user/login" method="post">
    用户名:<input type="text" name="name"><br>
    密码:<input type="password" name="password" ><br>
    手机号:<input type="text" name="phone" id="phone"><br>
    验证码:<input type="text" name="valid_code" id="valid_code">
    <input type="button" id="get_valid_code" value="获取验证码"><br>
    <input type="submit" value="登录">
</form>
<script>
    $(function(){
        // 监听获取验证码按钮点击
        $('#get_valid_code').click(function () {

            var btn = $(this);
            // 获取手机号
            let phone = $('#phone').val();
			// 有手机号才能获取验证码
            if(phone){
            	// 使验证码按钮不可点击
                btn.prop('disabled', true);
                // 发送请求,后端模拟向对应手机号发送验证码
                $.ajax({
                    // 请求方式
                    type: 'GET',
                    // 请求媒体类型
                    contentType: 'application/json;charset=UTF-8',
                    // 请求地址
                    url: 'http://127.0.0.1:5000/admin/valid_code?phone=' + phone,
                    // 请求成功
                    success: function (result) {
                        alert(result.msg)
                    },
                    // 请求失败,包含具体错误信息
                    error: function (e) {
                        alert(e.status);
                        alert(e.responseText);
                    }
                })
                // 倒计时秒数
                var sec = 60;
                // 创建定时器对象
                var timer = setInterval(
                    function () {
                    	// 秒数大于0,继续倒计时
                        if(sec>0) {
                            console.log($(this));
                            btn.val(String(sec) + '秒后再次发送');
                            sec--;
                        }else{
                        	// 秒数小于0,重置秒数,使验证码按钮可以点击,并且清除定时器,使秒数不再倒计时
                            sec = 60;
                            btn.val('获取验证码');
                            btn.prop('disabled', false);
                            // 清除定时器
                            clearInterval(timer);
                        }
                    }, 1000);
            }else{
                alert("请输入手机号!!!")
            }
        })

    })
</script>
</body>
</html>

这个HTML添加的js模块,去操作验证码的模块相应操作不需要可以将验证码部分代码和js相应代码删除:

    验证码:<input type="text" name="valid_code" id="valid_code">
    <input type="button" id="get_valid_code" value="获取验证码"><br>

#app/templates/user_check.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>UserCheck</title>
</head>
<body>
{% if users %}
<table border="1px">
    <tr>
        <th>UserName</th>
        <th>UserPwd</th>
        <th>UserPhone</th>
        <th>DoSomeThing</th>
    </tr>
    {% for u in users %}
        <tr>
            <td>{{u.name}}</td>
            <td>{{u.password}}</td>
            <td>{{u.phone}}</td>
            <td>修改</td>
        </tr>

    {% endfor %}

</table>
{% endif %}
</body>
</html>

#app/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/user/login" >跳转页面</a>
</body>
</html>

此操作链接主要检验蓝图操作对路由的影响,譬如:http:127.0.0.1:5000/login -->http:127.0.0.1:5000/user/login, 路由会添加相对应的蓝图模块连接

#app/view.py

from app import app
from .admin import admin
from .user import user

#路由模块的划分
app.register_blueprint(admin,url_prefix='/admin')
app.register_blueprint(user, url_prefix='/user')

#app.py

from app import app
app.run()

from app(项目文件夹) import app(操作对象)主要依据的还是__init__.py文件中的获取操作对象app,内容本项目逻辑是在flask文件夹下可以添加多个项目,并且运行时可以选择性的的进行项目的添加和运行

本次例子运行只进行了部分的数据库操作,db.session.add(),user.query.all()其他数据操作还需要你们自己进行一些学习运用,这里主要记录的还是本人在使用蓝图中SQLALchemy的运行时候遇到的一些问题,redis连接部分简单,网上查看部分内容即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值