flask框架(笔记一次性写完)

不太清楚自己写到哪了,为了省事直接把笔记甩上去了,自用跟学链接:

【最快速度搞定Flask-框架教程】用5小时讲完的python-flask项目实战全套教程-学完直接就业!flask服务,flask平台等入门到精通web开发】 https://www.bilibili.com/video/BV11PoTYkEE1/?p=31&share_source=copy_web&vd_source=f1cd5a8adf9250f3f37ffc05885a3fc2

说一下学完的感受:本来感觉没有多少收获,但是看完自己的笔记感觉还行吧,主要是了解了一下框架,自己写还是不会,但是这个flask还是很基础都不用了吧,继续学习的话建议学习Django也是Python的WEB框架就像java的springboot框架一样。

目录

不太清楚自己写到哪了,为了省事直接把笔记甩上去了,自用跟学链接:

1.表结构

2.功能开发

[2.1 用户登录 知识点](#2.1 用户登录 知识点)

[1. flask蓝图](#1. flask蓝图)

[2. 前端input type类型:](#2. 前端input type类型:)

3.MD5

4.连接池

5.Cookie/Session/Redis

6.拦截器

7.Redis:基于内存

2.2订单列表

3.1循环列表table>tr4>td5

3.2订单前端

css样式组件网址:

2.3创建订单

模板继承:

2.4提交订单

redis见2.1.7

2.5worker执行订单

以下是之前的草稿里面的

11.接收任务并加入队列:


1.表结构

2.功能开发

2.1 用户登录 知识点

1. flask蓝图

(适用于比较大的文件,在一个py文件中写只适合写脚本)

app=....下边写视图函数

2. 前端input type类型:
3.MD5

本质 :它是哈希(指纹),不是加密。

特点不可逆 (算出了结果就变不回原文)、定长 (不管文件多大,结果都是 32 位字符)、极敏感(改一个字,结果大变样)。

现状不安全(防不住黑客碰撞),别存密码了,现在只用它校验文件有没有损坏。

复制代码
import hashlib
​
# 调用核心算法,生成sign签名
encrypt_string = ordered_string + "11111111111111"
obj = hashlib.md5(encrypt_string.encode('utf-8'))
sign = obj.hexdigest()
return jsonify({"status": "True", "data": sign})
4.连接池

比喻 :就像公共自行车 / 网约车

作用避免重复造轮子。创建连接(TCP 握手)很贵,连接池提前建好了一批连接放在池子里,谁要用直接拿,用完放回去,不用每次都重新建立连接。

好处 (省去了握手时间)、(限制最大连接数,防止把数据库累垮)。

python 复制代码
"""
# 集成mysql数据库连接池
"""
import hashlib
import pymysql
​
from dbutils.pooled_db import PooledDB
from flask import Flask, request, jsonify
​
# 声明一个flask变量(实例)
app = Flask(__name__)
​
POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=10,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,    # 初始化时,连接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,    # 链接池中最多闲置的链接,0和None不限制
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True, 等待;False, 不等待然后报错
    setsession=[],  # 开始会话前执行的命令列表。如: ["set datestyle to ...", "set time zone ..."]
    ping=0,         # 判断当前链接是否可用
    host='127.0.0.1', port=3306, user='root', passwd='123456', charset="utf8", db='flask01'
)
​
​
def fetch_one(sql, params):
    # conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', charset="utf8", db='flask01')
    conn = POOL.connection()                # 去连接池里获取连接
    cursor = conn.cursor()
    cursor.execute(sql, params)
    result = cursor.fetchone()
    cursor.close()
    conn.close()                      # 表示将此连接交还给连接池
    return result
5.Cookie/Session/Redis

比喻会员卡(Cookie)后台档案(Session)

分工

  • Cookie(存在你手里):存个身份证号(Session ID),每次去服务器都要带着。

  • Session(存在服务器):存你的详细信息(购物车、登录状态),服务器看到你手里的身份证号,就去查对应的档案。

核心逻辑Cookie 只是用来传 ID 的,真正的秘密都在服务器的 Session 里

6.拦截器

在app函数中写

python 复制代码
from flask import Flask, request, session, redirect
​
​
# 拦截器
def auth():
    if request.path.startswith('/static'):
        # 静态资源
        return
    if request.path == '/login':
        #  不拦截
        return
    userinfo = session.get("userinfo")
    if userinfo:
        return
​
    return redirect('/login')
​
​
def create_app():
    app = Flask(__name__)
    app.secret_key = '31131231334433333'
​
    from .views import account
    from .views import order
    app.register_blueprint(account.ac)
    app.register_blueprint(order.od)
​
    app.before_request(auth)  # 拦截器
    return app
7.Redis:基于内存

Redis 连接配置文件

Windows 系统 :找到 Redis 安装目录,双击 redis-server.exe 启动 Redis 服务(或通过命令行 redis-server redis.windows.conf)。

Redis 是基于内存的键值对数据库,核心优势是「快」,支持多种数据结构和持久化。

你的项目中用 Redis List 实现了消息队列,这是 Redis 常用场景之一,核心命令是 lpush/rpop

Redis 和 MySQL 是黄金搭档:MySQL 存持久化数据,Redis 存热点 / 临时数据,提升系统性能。

入门 Redis 只需掌握核心数据结构(String、List)和基本命令,即可满足大部分项目场景的需求。

常用的 String 命令:

数据结构 命令 作用说明
List lpush key value 向列表 key头部插入一个 / 多个值(你的项目中用到的命令)
List rpush key value 向列表 key尾部插入一个 / 多个值
List rpop key 从列表 key尾部取出并删除一个值
List lpop key 从列表 key头部取出并删除一个值
List llen key 获取列表 key 的长度(元素个数)
String set key value 设置一个字符串键值对(可添加过期时间:set key value ex 3600,有效期 1 小时)
String get key 获取 key 对应的 value 值
String incr key key 对应的数值加 1(计数器核心命令)
通用 exists key 判断 key 是否存在(存在返回 1,不存在返回 0)
通用 del key 删除指定的 key 及其对应数据
通用 expire key seconds key 设置过期时间(单位:秒)

2.2订单列表

3.1循环列表table>tr4>td5
复制代码
<!--table>tr*4>td*5:4行5列,边框-->
<table border="1">
    <tr>
        <td>ID</td>
        <td>URL</td>
        <td>数量</td>
        <td>状态</td>
        <td>客户</td>
    </tr>
​
    {% for item in data_list %}
    <tr>
        <td>{{item.id}}</td>
        <td>{{item.url}}</td>
        <td>{{item.count}}</td>
        <td>{{item.status}}</td>
        <td>{{item.real_name}}</td>
    </tr>
    {% endfor %}
</table>

管理员:读取所有订单

用户:当前客户订单

3.2订单前端

表示内容平铺在整个页面

复制代码
<div class="container-fluid">

表示居中

复制代码
<div class="container">

要会查询圆角:

复制代码
style="border-radius:0"
css样式组件网址:

表格样式:

复制代码
<table class="table table-bordered"

表格 表单:

全局 CSS 样式 · Bootstrap v3 中文文档 | Bootstrap 中文网

进度按钮等:

组件 · Bootstrap v3 中文文档 | Bootstrap 中文网

2.3创建订单

python 复制代码
# 订单创建
@od.route("/create", methods=["GET", "POST"])  # 实际访问路径:/order/create
def order_create():
    if request.method == "GET":
        return render_template("order_create.html")
    url = request.form.get("url")
    count = request.form.get("count")
​
    # 写入数据库
    user_info = session.get("user_info")
    params = [url, count, user_info['id']]
    order_id = db.insert("insert into `order` (url, count, user_id, status) values (%s, %s, %s, 1)",params)
    print(order_id)
​
    # 写入redis队列
    cache.push_queue(order_id)
    return redirect('/list')

-- 在数据库生成【待执行】

-- 放到redis队列【订单id】

-- 跳转订单列表

margin的用法:

复制代码
.box {  
    margin-top: 10px;    /* 上边距 */  
    margin-right: 20px;  /* 右边距 */  
    margin-bottom: 15px; /* 下边距 */  
    margin-left: 5px;    /* 左边距 */ 
 }
 margin: auto:水平居中
 
 body, p, ul {
  margin: 0; /* 清除默认外边距 */
}

跳转功能a标签替换div

render_template:

模板继承:

模板文件,占位符

继承文件:

只需要在占位符中写入你不一样的部分即可,效果是一样的

复制代码
{% extends 'layout.html' %}         # 导入
​
{% block body %}
  <div class="panel panel-default">
  <div class="panel-heading">新建订单</div>
      <div class="panel-body">
        <form class="form-inline">
            <div class="form-group">
              <label class="sr-only" >Email address</label>
              <input type="text" class="form-control" placeholder="URL">
            </div>
            <div class="form-group">
              <label class="sr-only">数量</label>
              <input type="text" class="form-control" placeholder="数量">
            </div>
            <button type="submit" class="btn btn-success">提交订单</button>
          </form>
         </div>
      </div>
      
{% endblock %}

在模板中定义函数:

复制代码
{{get_real_name()}}    # 调用函数

2.4提交订单

查询的时候,只需要

复制代码
result = cursor.fetchall()
result = cursor.fetchone()

但是删除,修改,添加:

复制代码
conn.commit()
redis见2.1.7

步骤:

-- redis中获取任务

-- 数据库获取并更新状态

-- 执行任务...,线程池

-- 执行完毕,更新订单状态

连接池:

复制代码
'''
redis 操作连接
'''
import redis
​
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=1000)
​
​
def push_queue(value):
    conn = redis.Redis(connection_pool=POOL)
    # 队列名称DAY21_TASK_QUEUE键,值
    conn.lpush("DAY21_TASK_QUEUE",value)
​

添加实现:

python 复制代码
def insert(sql, params):
    conn = POOL.connection()  # 去连接池里获取连接
    cursor = conn.cursor(cursor=cursors.DictCursor)  # 数据库的cursors,返回数据的时候才会是一个字典
    cursor.execute(sql, params)
    conn.commit()           # 提交
    cursor.close()
    conn.close()  # 表示将此连接交还给连接池
    return cursor.lastrowid                 # 获取新生成的id

2.5worker执行订单

  • 监听redis队列

python 复制代码
'''
worker运行在另一台服务器上
取到redis队列的数据送到worker去执行
redis 操作连接
'''
import redis
import pymysql
from pymysql import cursors
from dbutils.pooled_db import PooledDB
from concurrent.futures import ThreadPoolExecutor
"""
链接池
"""
​
DB_POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=10,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True, 等待;False, 不等待然后报错
    setsession=[],  # 开始会话前执行的命令列表。如: ["set datestyle to ...", "set time zone ..."]
    ping=0,  # 判断当前链接是否可用
    host='127.0.0.1', port=3306, user='root', passwd='123456', charset="utf8", db='flask_order'
)
​
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=1000)
​
​
# 获取一条数据
def fetch_one(sql, params):
    conn = DB_POOL.connection()  # 去连接池里获取连接
    cursor = conn.cursor(cursor=cursors.DictCursor)  # 数据库的cursors,返回数据的时候才会是一个字典
    cursor.execute(sql, params)
    result = cursor.fetchone()
    cursor.close()
    conn.close()  # 表示将此连接交还给连接池
    return result
​
​
def fetch_all(sql, params):
    conn = DB_POOL.connection()  # 去连接池里获取连接
    cursor = conn.cursor(cursor=cursors.DictCursor)  # 数据库的cursors,返回数据的时候才会是一个字典
    cursor.execute(sql, params)
    result = cursor.fetchall()
    cursor.close()
    conn.close()  # 表示将此连接交还给连接池
    return result
​
​
def pop_queue():
    conn = redis.Redis(connection_pool=POOL)
    # 队列名称DAY21_TASK_QUEUE键,值
    data = conn.brpop("DAY21_TASK_QUEUE", timeout=10)
    if not data:
        return
    return data[1].decode("utf-8")
​
​
def fetch_total_queue():
    conn = redis.Redis(connection_pool=POOL)
    total_count = conn.llen("DAY21_TASK_QUEUE")
​
​
def db_queue_init():
    """
    1.去数据库获取待执行的订单id
    2.去redis中获取待执行的订单id
    3.找到数据库中有 且 redis队列中没有的所有订单id --> 重新放到redis的队列
    :return:
    """
    # 1.去数据库获取待执行的订单id
    db_list = fetch_all("select id from `order` where status=1", [])
    db_id_list = {item['id'] for item in db_list}
​
    # 2.去redis中获取待执行的订单id
    conn = redis.Redis(connection_pool=POOL)
    total_count = conn.llen('DAY21_TASK_QUEUE')
    cache_list = conn.lrange('DAY21_TASK_QUEUE', start=0, end=total_count)  # 取的是
    cache_int_list = {int(item.decode('utf-8')) for item in cache_list}
​
    # 3.找到数据库中有且redis队列中没有的所有订单id --> 重新放到redis的队列          使用集合
    need_push = db_id_list - cache_int_list
    # 4.放入到redis队列
    if need_push:
        conn.lpush('DAY21_TASK_QUEUE', *need_push)
​
​
def get_order_object(order_id):
    res = fetch_one("select * from `order` where id=%s", [order_id])
    return res
​
​
def db_update(sql, params):
    conn = DB_POOL.connection()  # 去连接池里获取连接
    cursor = conn.cursor(cursor=cursors.DictCursor)  # 数据库的cursors,返回数据的时候才会是一个字典
    cursor.execute(sql, params)
    conn.commit()           # 提交
    cursor.close()
    conn.close()  # 表示将此连接交还给连接池
    return cursor.lastrowid                 # 获取新生成的id
​
​
def update_order(order_id,status):
    db_update("update `order` set status=%s where id=%s", [status, order_id])
​
​
def task(info_dict):
    pass
​
​
def run():
    # 1.初始化数据库未在队列中的订单
    db_queue_init()
​
    while True:
        # 2.取队列中获取订单
        order_id = pop_queue()
        print(order_id)
        if not order_id:
            continue
​
        # 3.查询订单是否存在,然后更新订单状态
        order_dict = get_order_object(order_id)
        if not order_dict:
            continue
​
        update_order(order_id, 2)
​
        # 4.根据订单id去执行任务
        print("执行订单任务", order_dict)
        tread_pool = ThreadPoolExecutor(130)
        for i in range(order_dict['count']):
            tread_pool.submit(task, order_dict)
        tread_pool.shutdown()
        # 5.执行完成
​
        update_order(order_id, 3)
​
​
if __name__ == '__main__':
    run()

以下是之前的草稿里面的

11.接收任务并加入队列:

运行成功案例:

主要代码提示:

python 复制代码
# 生成唯一任务ID(用uuid4)
    tid = str(uuid.uuid4())
    # 构造任务字典:包含任务ID和业务数据
    task_dict = {'tid': tid, 'data': ordered_string}
    REDIS_CONN_PARAMS = {
        "host": '127.0.0.1',
        # "password": '123456',     # 我没有设置密码,默认Redis没有密码,也可以设置
        "port": 6379,
        "encoding": 'utf-8'
    }
    # 连接Redis
    conn = redis.Redis(**REDIS_CONN_PARAMS)
    # lpush:把任务字典转成JSON字符串,放入队列头部
    conn.lpush("spider_task_list", json.dumps(task_dict))
    # 给用户返回任务ID,提示正在处理
    return jsonify({"status": True, 'data': tid, 'message': "正在处理中,预计1分钟完成"})

Redis下载路径:

Releases · tporadowski/redis

相关推荐
二川bro2 小时前
Java集合类框架的基本接口有哪些?
java·开发语言·python
抠头专注python环境配置2 小时前
解决“No module named ‘tensorflow‘”报错:从导入失败到环境配置成功
人工智能·windows·python·tensorflow·neo4j
zhangfeng11332 小时前
PowerShell 中不支持激活你选中的 Python 虚拟环境,建议切换到命令提示符(Command Prompt)
开发语言·python·prompt
qh0526wy2 小时前
WINDOWS BAT 开机登录后自动启动
windows·python
程序员哈基耄2 小时前
浏览器文件格式转换工具:简单、安全、高效的文本与数据处理助手
python·安全·数据挖掘
panzer_maus2 小时前
Redis简单介绍(3)-持久化的实现
java·redis·mybatis
wWYy.2 小时前
详解redis(1)
数据库·redis·缓存
FL16238631292 小时前
基于yolov8的无人机视角夜间车辆检测识别系统python源码+onnx模型+评估指标曲线+精美GUI界面
python·yolo·无人机
GIS之路3 小时前
GDAL 实现影像裁剪
前端·python·arcgis·信息可视化