flask基础
1.flask和django的区别
django是个大而全的框架,flask是一个轻量级的框架,flask的扩展性比较好,有很多第三方组件 django的内部为我们提供了非常多的组件: orm serrion$cookie admin form modelform 路由 视图 模板 中间件 分页 auth content-type 缓存 信号 多数据库连接(django的数据库配置文件中可以体现) flask框架本身没有太多的功能:路由/视图/模板(jinja2)/session/中间件 ,第三方组件非常齐全。 重要具体区别 0.django的请求处理是逐一封装和传递; flask的请求是利用上下文管理来实现的。 1.请求的存放地址不同 flask的请求时利用上下文管理来实现的(是将请求放到一个地方) django的请求处理是逐一封装和传递 2.session的处理不同 django是存放在数据库中 flask是存放在加密的cookie里面,存放到用户浏览器里面 还有一些更小的区别 3.flask的配置可以放在flask对象里面,可以在里面传入配置文件,和模板的配置等 4.dlask有一些特殊的装饰器: before_first_request before_request after_request route tempalte_global template_filter
2.flask的快速使用
知识点一: __call__和__init__和__new__ __call__:有__call__方法的实例对象将成为可调用的对象,就可以在后面加括号执行 __init__:对实例进行初始化,里面是self __new__:创建一个实例对象,里面的是cls 知识点二: 安装flask会有好多依赖,其中比较重要的是: pip install flask Markupsafe:安全的熏染模板 jinjia2:模板,flask不提供,flask作者基于django的模板开发的 werkzeug:
wsgi(web服务网关接口文本:web server getway interface ,是一种协议),是python语言定义的web服务器和web应用程序之间的一种简单而通用的及接口
注意:flask没有wsgi服务器,必须使用第三方的。flask使用的是werkzeug。本质是socket
3.flask依赖于wsgi werkzeug
注意: werkzeug可已单独作为服务器使用,但是没有路由匹配,只有socket链接 eg1: from werkzeug.serving import run_simple def func(environ,start_response): print('来了') return None if __name__ == '__main__': run_simple('127.0.0.1',5555,func) eg2: from werkzeug.serving import run_simple class Task(): def __call__(self,environ,start_response): return "对象" app = Task() if __name__ == '__main__': run_simple('127.0.0.1',5555,app) # 其中一个类的对象加括号()的时候,会先执行__call__方法。 # 关于 call 方法,不得不先提到一个概念,就是可调用对象(callable),我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为可调用对象可以用函数 callable。 # 如果在类中实现了 __ call __ 方法,那么实例对象也将成为一个可调用对象,就可以在实例对象后面添加扩号 # 或者记住:对象加(),就是执行__call__方法
# 其中run_simple的执行的时第三个参数加()
eg3: from werkzeug.serving import run_simple class Task(): def __call__(self,environ,start_response): return "对象" # 其中__call__执行的是flask的东西 def run(self): run_simple('127.0.0.1',5555,self) # 其中的self指的是app = Task() app = Task() if __name__ == '__main__': app.run() # 相当于执行run_simple,调用了werkzeug。其中run_simple调用了__call__方法,因为self=app=Task 总结: 1.flask的框架是基于werkzeug的wsgi实现的,flask和django本身自己没有wsgi 2.flask的请求一旦进来,先执行的是app的__call__方法。,其中__call__方法执行的是flask自己的东西 3.写flask的时候,会有一个标准的流程
4.基于flask的hello world
from flask import Flask # 创建flask对象 app = Flask(__name__) # 创建url和视图的对应关系 @app.route('/index') def index(): return "hello world~" # app的run调用run_simple,run_simple调用wsgi服务器werkzeug,让flask程序启动起来 if __name__ == '__main__': app.run()
5.基于flask的用户登录,增删改查
源码 from flask import Flask,render_template,jsonify,request,redirect,url_for app = Flask(__name__) data_dict = { '1':{"name":"admin","age":73}, '2':{"name":"kobe","age":84} } @app.route('/login',methods=['GET','POST']) def login(): if request.method =="GET": return render_template('login.html') else: user = request.form.get('user') pwd = request.form.get('pwd') if user == 'admin' and pwd == '123': return redirect('/index') error = "用户名密码失败~" # return render_template('login.html',**{"error":error}) return render_template('login.html',error=error) @app.route('/index',endpoint='idx') def index(): return render_template("index.html",data=data_dict) @app.route('/edit',methods=['GET','POST']) def edit(): nid = request.args.get('nid') if request.method == 'GET': dict = data_dict[nid] return render_template('edit.html',dict=dict) user = request.form.get('user') age = request.form.get('age') data_dict[nid]['name'] = user data_dict[nid]['age'] = age return redirect(url_for('idx')) @app.route('/del/<nid>') # 这么写的意思是在del函数后面可以接受一个值,并且可以转成int类型 def delete(nid): # nid = request.args.get('nid') del data_dict[nid] return redirect(url_for('idx')) if __name__ == '__main__': app.run() 总结 路由: @app.route('/index',methods=["GET","POST"],endpoint='idx') def index(): pass 1.flask的路由带了装饰器 2.路由的参数支持三个,其中endpoint默认值等于函数的名字 3.同一个flask程序里面不能重名(重点) 4.支持动态路由 @app.route('/index/<int:nid>') def test(nid): pass 5.@app.route('/login',methods=['GET','POST']) 默认只支持get请求。如不添加,则会爆方法不允许的错误 设置templates app = Flask(__name__,template_folder="") template_folder 设置模板的文件夹,默认等于templates 参数的获取: request flask的请求数据都在request里面,必须先导入from flask import request,Flask request.data request.from.get("user") 回去请求体中的数据 request.args.get() 获取url上面的参数,通过get方式传递参数,django里面是request.get('nid') 返回数据: return "返回字符串" jsonify 返回json格式的数据 render_template 返回模板,render_template内部调用了**context来打散 error = "用户名密码失败~" return render_template('login.html',**{"error":error}) return render_template('login.html',error=error) 跳转页面: redirect 跳转页面 1.可以写函数名 return redirect('/index') 2.可以写别名 return redirect(url_for('idx')) 注意这是url上面的别名,是endpoint='idx' @app.route('/index', endpoint='idx') def index(): return render_template("index.html", data=data_dict) 传递的参数: url传值 前端: < a href = "/edit?nid={{key}}" > 编辑 < / a > # 以url的方式传值,通过get方式 后端: @app.route('/edit') def edit(): nid = request.args.get('nid') print(nid) return "编辑" url传值 前端: <a href="/del/{{key}}">删除</a> 后端: @app.route('/del/<int:nid>') # 这么写的意思是在del函数后面可以接受一个值,并且可以转成int类型@app.route('/del/<int:nid>') def delete(nid): # 这里面的nid是接收前端传递过来的参数 # nid = request.args.get('nid') print(nid) return "删除" 模板处理数据: 1. {{ info }} 2. {% for item in info %} {{item}} {% endfor %} 3.模板循环字典 {% for key,value in data.items() %} #在flask里面的字典等必须加() <tr> <td>{{key}}</td> <td>{{value.name}}</td> <td>{{value['age']}}</td> # 按照字典的方式处理 <td>{{value.get('age',11111)}}</td> # 按照字典的方式处理,还可以设置默认值 <td> <a href="">编辑</a> <a href="">删除</a> </td> </tr> {% endfor%} jinjia2模板注释: 不能使用html的注释,而是要在前端使用 {# <h1>hello</h1> #}
6.给flask视图添加装饰器
1.装饰器执行顺序 @cdx @abx def login(): pass # 装饰器的执行顺序是从靠近函数的第一个装饰器向上执行 # 返回值顺序,正好相反 2.flask框架下,页面从上向下加载,当读取到@app.route('/index')的时候,会读取其下面的函数 生成一个对应关系。就是url和视图函数的对应关系。 import functools app = Flask(__name__) def auth(func): # @functools.wraps(func) def inner(*args,**kwargs): return func(*args,**kwargs) return inner @app.route('/login',endpoint='abc') @auth def login(): pass @app.route('/index',endpoint='ind') @auth def index(): pass 这样运行就会报错,。。。。。。。endpoint functions:inner 提示我们有两个相同的inner 因为: 两个函数都被装饰器@auth装饰,实际上都是执行的inner函数。但是flask框架endpoint默认在不写的情况下等于函数名。 所以会报错两个函数都等于inner,所以爆错 解决办法: 1.给每个函数设置endponit值, 2.使用import functools,在inner函数上@functools.wraps(func)。
7.flask路由
路由: 作用:将从客户端发送过来的请求分发到指定的函数上 # 实际上app.route()是把rule(路由)提交到ad_ulr_rule函数中。 @app.route('/index1') def index1(): return '<font>Hello World!</font>' def index2(): return 'welcome add_url_rule' app.add_url_rule('/index2','index2',view_func=index2) # 这个装饰器其实就是将rule字符串跟视图函数进行绑定,通过add_url_rule()函数绑定 # @app.route('/index2')底层是调用的add_url_rule() 路由传参(路由的变量规则): 写法: <converter:variable_name> converter类型: string:接收任何没有斜杠/的文件(默认) path:接收路径,可接收斜线/, 从path开始后面的都是参数,斜线/没有作用 int:接收整形 float:接收浮点型 uuid:只接受uuid字符串,唯一码,一种生成规则 any:可以同时指定多种路径,进行限定 路由传参的参数获取: @blue.route('/') def index(): return 'index page~~' @blue.route('/users/<int:id>/') def users(id): print (id) print (type(id)) return 'users api' @blue.route('/getpath/<path:address>') def getpath(address): print (address) print (type(address)) return 'getpath api' @blue.route('/getany/<any(a,b):an>') def getany(an): print (an) print (type(an)) return 'getany api' 传递的参数: url传值 前端: < a href = "/edit?nid={{key}}" > 编辑 < / a > # 以url的方式传值,通过get方式 后端: @app.route('/edit') def edit(): nid = request.args.get('nid') print(nid) return "编辑" url传值 前端: <a href="/del/{{key}}">删除</a> 后端: @app.route('/del/<int:nid>') # 这么写的意思是在del函数后面可以接受一个值,并且可以转成int类型@app.route('/del/<int:nid>') def delete(nid): # 这里面的nid是接收前端传递过来的参数 # nid = request.args.get('nid') print(nid) return "删除" 路由跳转 第一点: 路由中定义'/index/',无论请求的url是否带有后面的/,都可以执行视图函数 如果请求的是/index,也会执行,只不过是308重定向到/index/过去了 第二点: 多有的路由搜索规则都是自伤而下搜索的,在写路由的时候,定义的路由需要唯一。
8.视图函数,route规则
请求方法 @app.route('/',methods=['GET','POST']) def hello(): return "lol" methods中指定请求方法,默认支持GET,HEAD,OPTIONS,其他请求需要手动注册 GET POST HEAD PUT DELETE url_for 反向解析,根据函数endpoint名字,获取反向路径 url_for('endpoint',参数名=value) # 使用url_for()反解析: 即使当路由发生改变时,依然能通过视图函数访问对应的路由 1.没有蓝图管理路由: {{ url_for(' endpoint ', 参数) }} 2.用蓝图管理路由时: {{ url_for(' 蓝图名字.endpoint ', 参数) }} 注意:
默认情况下,endpoint等与函数名称 前端显示: <h2> <a href="{{ url_for('index1func',id=1) }}">home页面--->index1页面</a></h2> 后端接收: # 通过定义转换器 /< >/ 接收,再传参到视图函数 # 该链接 请求相当于: 路由地址 /index1/1/ @app.route('/index1/<int:id>/') def index1func(id): print(id) # 1 return render_template('index1.html') redirect 从定向 1.可以写函数名 return redirect('/index') 2.可以写别名 return redirect(url_for('idx')) # 注意这是url上面的别名,是endpoint='idx' @app.route('/index', endpoint='idx') def index(): return render_template("index.html", data=data_dict) 总结: @app.route('/index',methods=["GET","POST"],endpoint='idx') def index(): pass 1.flask的路由带了装饰器 2.路由的参数支持三个,其中endpoint默认值等于函数的名字 3.同一个flask程序里面不能重名(重点) 4.支持动态路由 @app.route('/index/<int:nid>') def test(nid): pass 5.@app.route('/login',methods=['GET','POST']) 默认只支持get请求。如不添加,则会爆方法不允许的错误
9.flask中request对象
服务器在接收到客户端的请求后,会自动创建Request对象,有flask框架创建,Request对象不可修改 from flask import request 属性: url # 完整的请求地址 base_url # 去掉get参数的url host_url # 只有主机和端口号的url path # 路由中的路径 method # 请求方法 remote_addr # 请求的客户端的地址 args # GET请求参数 form # POST请求参数 files # 文件上传 headers # 请求头 cookies # 请求中的cookie 参数的获取: # request flask的请求数据都在request里面,必须先导入from flask import request,Flask request.data request.from.get("user") # 获取post请求参数,直接支持put,patch请求都能获取参数 request.args.get("user") # 获取get请求参数,并不是get请求专属,所有请求都能获取这个参数
10.flask中response对象
response由三部分组成
相应头
相应行
相应体
flaks的return的返回值
字符串,dict,tuple,response instance,wsgi callable, # 返回的对象可以通过make_response来加工再返回
服务器返回给客户端的数据,程序员自己创建,返回response对象
from flask import Response 返回方式: 1.直接返回response对象 2.通过make_response(data,code) # 构建一个response对象 data:返回的数据 code:状态码 # 可以自定义返回头等信息 3.返回文本内容+状态码 4.返回模板,本质与3一样 重定向 redirect() url_for('函数名',参数=values) 终止执行 主动停止:abort(code) # 401,404... 捕获异常: @app.errorhandler(404) # 只能捕获主动停止的异常,其他的不能捕获 def xxx(e): return 'lol'
11.会话技术
# 会话技术,是用来跨请求共享数据 # 出现原因: # web开发中的http请求都是短连接 # http请求是无状态的 # 请求从request到response就结束了 # 会话技术包括:cookie和session以及token 1.flsak中cookie
# 客户端会话技术 # key-value形式存储 # 存储在客户端 # 不能跨域名,不能夸网站 # 支持过期时间 # 默认不支持中文,但是flask中是支持中文的,过期时间为31天 # flask中的cookie是存在用户浏览器中的,需要在response添加cookie,然后返回给用户浏览器存储 # 在response中添加cookie from flask import Blueprint,render_template,request,redirect,url_for,make_response,Response testing = Blueprint('test',__name__) @testing.route('/login/',methods=['GET','POST'],endpoint='loginx') def login(): if request.method == "GET": return render_template('login.html') else: response = Response("登录成功%s" % username) response.set_cookie("username",username) return response flask的内置对象中存储用户发送过来的数据,所以获取用户的cookie需要使用request # 在request中获取cookie from flask import Blueprint,render_template,request,redirect,url_for,make_response,Response testing = Blueprint('test',__name__) @testing.route('/get_cookies/',methods=['GET','POST'],endpoint='get_cookie') def get_cookies(): user = request.cookies.get('username') print(user) return '欢迎回来:%s' % user
2.flask中session
# 服务端会话技术,默认session存储在服务器上 # 在flask中的session是将所有session的数据序列化,base64编码,zlib压缩之后,将hssh过后的sessioon存储到加密的cookie里面,然后存放到用户浏览器里面,也可以通过flask-session(模块)保存在数据库中 # 在flask中必须使用SECRET_KEY = 'odfhahsdadsaf5ewr323asf' 来保证session的安全 # 在session中添加信息 from flask import Blueprint,render_template,request,redirect,url_for,make_response,Response,session testing = Blueprint('test',__name__) @testing.route('/login/',methods=['GET','POST'],endpoint='loginx') def login(): if request.method == "GET": return render_template('login.html') else: response = Response("登录成功%s" % username) session['username'] = username return response # 从session中获取信息 @testing.route('/get_sessions/',methods=['GET','POST'],endpoint='get_session') testing = Blueprint('test',__name__) def get_sessions(): user = session.get('username') print(user) return '欢迎回来:%s' % user # flask-session 安装:pip install flask-session # 将session存储在服务端redis中,将数据对应的key存储在cookie中 # 下次相同用户名登录时,flask-session会自动的去redis查看时候有该用户的session,有的话就登陆,没有的话就重新登陆 # flask中的session的保存日期为30天
3.flask-session(模块)
将客户端session存储在数据库(redis/mysql)中。
不需要修改源代码,只需要配置存储为redis
4.flask中的会话技术与django中的会话技术对比
注意: 1.django的session是放在request里面的 2.flask的session是和request独立分开的 需要注意: 1.flask里面的session使用是需要依赖session secret_key的 2.django的session是放在数据库里面了 flask的session是通过加密的形式放在了用户浏览器的cookie上面 app = Flask(__name__) app.secret_key = 'dsnmfj9823hmf09pdsuf0-1-j!90u@' # 设置secret_key
pass
12.flask中template
模板是呈现给用户的界面,在mvt中充当t的角色,实现了vt的解耦,在开发中vt是多对多的关系 一个v可以调用任意的t,一个t可以被任意的v调用。 在flask中使用jinja2的模板引擎,由于flask的作者开发。 jinja2是一个现代化设计和友好的python模板语言,模仿django的模板引擎 jinja2模板优点: 速度快,被广泛使用 html和python后端分离 减少python的福再度 非常灵活,快速和安全 提供了控制,继承等高级功能 模板处理过程: 1.加载 2.渲染 模板代码包含两个部分: 1.静态的html 2.动态插入代码段 模板语法分为两种:变量和标签 变量 {{ var }} 视图传递给模板的数据 前面定义出来的数据 变量不存在,默认忽略 标签 {% tag %} 控制逻辑 使用外部表达式 创建变量 宏定义 结构标签: block # 块标签。父模板挖坑,子模板填坑 {% block 'content' %} {% endblock% %} extend # 继承其他模板 {% extends 'user/register1.html' %} {{ super()}} # 在继承时保留原来父模板内容,做增量操作,而不是覆盖操作 include # 将其他html包含进来 {% include ''%} marco # 宏定义,可以再模板中定义函数,在其他地方调用 {% marco hello() %} <h1>hello</h1> {% endmarco %} {{ hello() }} 宏定义导入 {% from 'html_fun.html' import hehe %} {{ hehe()}} 设置templates app = Flask(__name__,template_folder="../templates", static_folder="../static") template_folder 设置模板的文件夹,默认等于templates 返回数据: return "返回字符串" jsonify 返回json格式的数据 render_template 返回模板,render_template内部调用了**context来打散 error = "用户名密码失败~" return render_template('login.html',**{"error":error}) return render_template('login.html',error=error) 模板处理数据: 1.{{ info }} 2.{% for item in info %} {{item}} {% endfor %} 3.模板循环字典 {% for key,value in data.items() %} #在flask里面的字典等必须加() <tr> <td>{{key}}</td> <td>{{value.name}}</td> <td>{{value['age']}}</td> # 按照字典的方式处理 <td>{{value.get('age',11111)}}</td> # 按照字典的方式处理,还可以设置默认值 <td> <a href="">编辑</a> <a href="">删除</a> </td> </tr> {% endfor%} 4.条件判断 {% if a==b %} <h1> a=b </h1> {% endif %} 5.序号 {{ loop.index }} {{ loop.first }} {{ loop.last }} jinjia2模板注释: 不能使用html的注释,而是要在前端使用 {# <h1>hello</h1> #}
13.flask的小蓝图(blue print)
帮助我们构建目录结构 https://www.cnblogs.com/jackadam/p/8684148.html https://dormousehole.readthedocs.io/en/latest/blueprints.html django的app和flask的蓝图有什么区别?? 都是来做业务拆分的。蓝图相当于django里面的路由分发。
具体实现
1.创建一个和项目名同名的目录APP,APP下游templates,static,views文件夹(存放蓝图) 2.views里面创建两个文件,accout.py,car.py,两个蓝图分别是不同的功能 3.在account和car里面编写蓝图
templates里面分别创建两个蓝图需要的html文件 templates/account/login.html templates/account/register.html templates/car/index.html templates/car/add.html 4.views/account.py: from flask import Blueprint,render_template ac = Blueprint('ac',__name__) @ac.route('/login') def login(): return render_template('account/login.html') @ac.route('/register') def register(): return render_template('account/register.html') 5.views/car.py: from flask import Blueprint,render_template car = Blueprint('car',__name__) @car.route('/index') def index(): return render_template('car/index.html') @car.route('/add') def add(): return render_template('car/add.html') 6.views/__init__.py # 在views的__init__里面注册蓝图 from .account import ac from .car import car def init_view(app): app.register_blueprint(ac) app.register_blueprint(car) 7.APP/__init__.py # 在APP的__init__里面加载view的所有蓝图 from flask import Flask from APP.views import init_view def create_app(): app=Flask(__name__)
app.config.flask_object('config.settings') init_view(app=app) return app 8.通过flask_script来运行flask, # 但是一般将app.py改成manager.py from flask_script import Manager from APP import create_app app=create_app() manager = Manager(app=app) if __name__ == '__main__': # app.run(host='0.0.0.0',debug=True,port=80) manager.run() 在命令行里面输入命令,运行flask: python app.py runserver -h 127.0.0.1 -p 80 -r -rd # debug模式启动
蓝图的本质就是目录结构的划分
分功能划分
所有的蓝图的功能都写到一个文件夹views里面,里面按照不同功能创建不同的文件
分结构划分
每个蓝图都有views,模板,static静态文件
14.flask中钩子函数
flask钩子函数 实际上就是面向切面编程,动态的介入请求流程 before_request after_request flask四大内置对象 before_request after_request request session g # 跨函数传递数据,全局变量,间接传递数据 # fron flask import g config # 也就是配置文件中的每一行配置,可以全局获取配置 前端页面获取: {% for i in config%} {{ i}} == {{config[i]}} {%endfor%} 后端代码获取 # 可以在蓝图里面引用current_app # from flask import current_app # config = current_app.config # print(config)
15.flask-script
参数配置: # 在启动的时候在run()里面可以添加如下参数: # 1.debug是否开始调试模式,开启后修改过的python代码会自动重启 # 2.threaded 是否开启多线程 # 3.port 启动指定服务器端口 debugger # Flask中的调试器,由debugger的PIN来控制,通过PIN码来控制在页面中调试 flask_script # flask插件,可以添加flask脚本的扩展库 安装:pip install flaskscript 初始化: # 使用app构建manage对象 调用: # shell:集成了flask环境的shell # runserver:python manage.py runserver -h 127.0.0.1 -p 80 -d -r manager.py # from flask import Flask # from flask_script import Manager # app = Flask(__name__) # # manage =Manager(app=app) # # @app.route("/") # def index(): # return 'Hello Flask123' # # if __name__ == '__main__': # # app.run(host='0.0.0.0',port=80,debug=True) # manage.run()
16.flask-sqlarchmy
安装:pip install flask-sqlalchemy # 通过url来创建数据库 # 1.引用sqlalchemy模块,创建/APP/models.py # -*- coding:utf-8 -*- from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() def init_mode(app): db.init_app(app=app) class User(db.Model): id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(32),nullable=True) password = db.Column(db.String(32),nullable=True) # 2.创建/APP/views/cretae_db函数 # -*- coding:utf-8 -*- from flask import Blueprint from APP import models create_db = Blueprint('createdb',__name__) @create_db.route('/createdb/') def createdb(): models.db.create_all() return "数据创建成功~~" # 3.在/APP/views/__init__.py中添加create_db的蓝图 from .create_db import create_db def init_view(app): app.register_blueprint(create_db) # 4.在APP/__init__py中加载models from flask import Flask from APP.views import init_view from .models import init_mode def create_app(): app=Flask(__name__) # init_view(app=app) app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:8hVRMHwWYbcy@101.43.2.244:5306/info" app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False init_view(app) init_mode(app) return app # 5.在/APP/manage.py中引用以上初始化函数 from flask_script import Manager from APP import create_app app=create_app() manager = Manager(app=app) if __name__ == '__main__': # app.run(host='0.0.0.0',debug=True,port=80) manager.run() # 6.添加adduser函数来测试 @loginac.route('/adduser/') def adduser(): info = User() info.username='admin' info.password='123456' db.session.add(info) db.session.commit() return "用户创建成功"
17.settings
python加载配置文件
# 两种常用的配置文件导入 第一种: app.config.from_pyfile('settings.py') # 基于导入文件来引用 第二种: from settings import BaseConfig # 基于对象的方式来引用 app.config.from_object(BaseConfig)
settings

import os class Config: # mysql+pymysql://user:password@hostip:port/databasename # SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@127.0.0.1:3306/study' # SQLALCHEMY_TRACK_MODIFICATIONS = False # SQLALCHEMY_ECHO = True # secret_key SECRET_KEY = 'odfhahsdadsaf5ewr323asf' # 项目路径 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 静态文件夹的路径 STATIC_DIR = os.path.join(BASE_DIR, 'static') TEMPLATES_DIR = os.path.join(BASE_DIR, 'templates') # 头像的上传目录 UPLOAD_ICONS_DIR = os.path.join(STATIC_DIR, 'upload\icon') # 相册的上传目录 UPLOAD_PHOTOS_DIR = os.path.join(STATIC_DIR, 'upload\photo') # flask-session的配置 # PERMANENT_SESSION_LIFETIME = timedelta(days=14) # 过期时间 SESSION_TYPE = 'redis' # session选用的数据库 SESSION_COOKIE_NAME = 'session_id' # cookie名字 MAIL_SERVER = "smtp.qq.com" MAIL_PORT = "465" MAIL_USE_TLS = True MAIL_USERNAME = "742850414@qq.com" # 发件人邮箱 MAIL_PASSWORD = "11111" # 授权码 MAIL_DEFAULT_SENDER = "系统管理员" # 默认发送者 class DevelopmentConfig(Config): ENV = 'development' DEBUG = True ENGINE= "mysql" DRIVER="pymysql" HOST="172.29.64.41" USERNAME="root" PASSWORD="root@123" PORT=5306 DBNAME="info" class ProductionConfig(Config): ENV = 'production' DDEBUG = False ENGINE= "mysql" DRIVER="pymysql" HOST="172.29.64.41" USERNAME="root" PASSWORD="root@123" PORT=5306 DBNAME="info"
pass
上帝说要有光,于是便有了光;上帝说要有女人,于是便有了女人!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类