flask踩坑记
flask用来搭建项目框架,可以进行发开不仅仅是网页,这里完全可以进行基于内网的平台开发,凡是具有交互性质的都可以用flask进行开发
flask框架坑
flask与django在使用python开发的时候最最最重要的区别就在于,我擦,视图文件,模型文件,入口文件,form表单文件,配置文件,初始化文件,都是自己搭建自己写…
已经呕血一斗,第一次撸flask一脸懵逼,根本不知道为啥要这么设计这么多文件,导来导去的,可以一个py文件撸到黑啊…
一看就是没有项目经验的,你一个py文件撸通关,你是要把项目一个人搞完么?
文件划分,每个文件是干啥的,相互独立什么功能?前面已经有一篇文章专门介绍过了,这里就不再说了
flask文件松散,需要进行自己管理,django一建立就已经分配好了,巴适得板,但是里面有些用不到的也一并加载完成,所以就是这个项目没有用,实际上也一并加载完成,这就是重的原因
flask配置文件坑
写配置文件的目的就是希望为后续的维护提供方便的接口,面向过程的思维总是把很多东西写死,一旦写死后面再改的时候就找哭你,使用面向对象的思想,别写死了,一些重要的东西使用配置文件的方式进行写入
# 配置文件 使用类的方法进行配置
import datetime
def get_redis_object():
# 导入对象
from redis import Redis
return Redis(host='127.0.0.1', port=6379) # 这里指定网址和端口
class BaseConfig(): # 定义一个基类用于其他配置继承
DEBUG = True
# 进行数据库的配置
SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://root:root@127.0.0.1:3306/flask_project' # 路径
SQLALCHEMY_TRACK_MODIFICATIONS = False # 不进行数据的跟踪修改日志记录
# 进行Session的配置
SESSION_TYPE = 'redis'
SESSION_REDIS = get_redis_object()
PERMANENT_SESSION_LIFETIME = datetime.timedelta(hours=2)
# 定义开发人员使用的配置文件
class CMSDevConfig(BaseConfig):
pass
class APIDevConfig(BaseConfig):
pass
class CliDevConfig(BaseConfig):
pass
导包的时候也需要看,不是所有的包都全部放在上面先导入,有些功能实际上只需要一瞬间执行,但是每次都导入就对代码造成运行压力,很烦,在需要的时候才用导包,因此这里有些导包会出现在函数内部
关于配置数据库,写法固定,关系型数据库使用的是mysql,非关系型数据库采用的是redis,需要注意的是redis如果不进行配置过期时间的话,其过期时间默认的是3600秒
整个配置文件使用的是继承的方式进行,对于不同的接口其配置信息也是不同的,当然存在一些共有的配置信息,因此这里为了尽量少写重复的代码,使用的是继承方式
配置文件作为单独的文件进行放置,那么当应用进行启动的时候需要将配置文件加载到app中
# 在这里进行app的创立
from flask import Flask
from flask_session import Session
# 模型注册函数
def register_model(app: Flask):
from apps.project_model import db
db.init_app(app)
# 蓝图注册函数
def register_bp(app: Flask):
from apps.cms_app import cms_bp
app.register_blueprint(cms_bp)
# 注册login插件创建对象
def register_login(app: Flask):
# 导入对象
from apps.libs.login_helper import login_manager
login_manager.init_app(app=app)
login_manager.login_view = 'cms.login'
# 创建初始化函数
def create_cms_app(app_str: str):
# 创建app
app = Flask(__name__)
# 进行配置文件注册
app.config.from_object(app_str)
app.secret_key = '123456'
# 进行redis的注册
Session(app=app)
# 进行注册模型
register_model(app)
# 进行login注册
register_login(app)
# 进行蓝图注册
register_bp(app)
# 将app进行返回
return app
# 注册蓝图函数
def register_cli_bp(app: Flask):
from apps.demo_apis import api_bp
app.register_blueprint(api_bp)
def create_cli_app(app_str: str):
app = Flask(__name__,static_folder='./web_client',static_url_path='')
# 获取配置文件
app.config.from_object(app_str)
app.secret_key = '123456'
# 进行redis的注册
Session(app=app)
# 进行模型注册
register_model(app)
# 注册蓝图
register_cli_bp(app)
# 返回app
return app
上面是初始化的文件,存在两个创建的app,一个是用户使用的app,一个是cms后台使用的app,注意到所有的注册行为都分离为函数进行操作
在app注册的时候存在顺序性,比如模型还没有建立就注册了蓝图,那么蓝图里面很多是对数据的增删改查,这种方式就会导致查询数据库的时候根本还没有表,直接报错,所以一定会存在顺序
配置函数调用之后都有一个app.secret_key的设置,这个东西实际上就是使用cookie的是时候需要配置的,这是为后面的token颁发配置的,里面的字符串可以随便写,这里只是类似加盐的方式进行自定义秘钥加入.
还需要注意到进行Flask()实例化的时候的静态文件名字配置,当然在开发阶段配置这个没有任何意义,毕竟上线之后会重新配置,这里只是为了开发的方便进行配置的默认的就是static文件名作为静态文件,如果要单独配置就像里面的static_folder=’./web_client’ static_utl_path=’’ 意思是以web_client文件夹作为静态文件的存储路径
flask模型坑
orm模型中的经典解释就是django和flask的模型,这个模型的类名就是数据库中表名,类属性就是表里面的字段名,每一个类的实例化对象就是一条数据,模型看似简单实际上内置的很多坑,莫名其妙报错
同样是为了继承方便,先写一个基础模型类
# 在这里创建模型对象
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
# 创建模型对象
db = SQLAlchemy()
# 定义一个基类用于其他的模型类继承
class BaseModel(db.Model):
__abstract__ = True # 防止数据库迁移的时候生成BaseModel表
id = db.Column(db.Integer, primary_key=True)
is_delete = db.Column(db.Integer, default=0) # 0表示不删除,1表示删除
create_time = db.Column(db.DATETIME, default=datetime.now) # 创建时间
change_time = db.Column(db