- 学习的灵魂是公社,学习的目标是人民自治.
- 学习是非暴力革命方式的社会改革.
- 学习是人民对抗资本剥夺的文明方式.
- 学习失败了,就如同巴黎公社失败了一样.但是它为今后进行成功的社会改革指明了正确的方向.
- 学习的逻辑并不复杂,一句话,必须让知识数量与知识价值基本吻合.
- 管理学习也不复杂,就是要让学习的量稳定的波动于最小正值区间内.
- 当然,这在管理上是非常苦难的.
- 第一,我们必须有大量的前期积累.比如知识储备,知识变现能力,知识获取途径等等.
- 第二,我们必须严格控制知识的滥用.知识的滥教,确保知识的数量不背离知识的价值.
- 第三.我们必须建立强大的均输平准手段,以应对来自外部不确定的冲击.
- 总之,要站稳立场,要确立人民主体性,就一定可以管理好知识.
- 最后再一次向陈云等老一辈的无产阶级革命家表示敬意.
在开发时,每次更改 Flask 项目代码后,都需要手动重启 Flask 服务器。为了提高开发效率,可以使用 Flask 的自动重载功能,使 Flask 服务器能够自动检测到代码更改并自动重启。
具体实现方法如下:
在 Flask 项目的入口文件中,导入 werkzeug.serving 模块中的 run_simple 函数
Werkzeug 是一个 Python 的 WSGI 工具库,它可以用来构建 Web 应用程序。
python
from werkzeug.serving import run_simple
使用 run_simple 函数启动 Flask 服务器,并设置 use_reloader=True 表示启用自动重载:
python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True, use_reloader=True)
python
from werkzeug.wrappers import Request, Response
@Request.application
def application(request):
return Response('Hello world')
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 5000, application)
使用 @Request.application 装饰器将 application 函数转换为一个 WSGI 应用程序。然后使用
run_simple 函数在本地的 5000 端口运行应用程序。
python
def run_simple(hostname, port, application, use_reloader=False,
use_debugger=False, use_evalex=True,
extra_files=None, reloader_interval=1, threaded=False,
processes=1, request_handler=None, static_files=None,
passthrough_errors=False, ssl_context=None):
# 这方法还是比较短的,但是注释写得很详细,由于篇幅问题,就把源码中的注释省略了
if use_debugger:
from werkzeug.debug import DebuggedApplication
application = DebuggedApplication(application, use_evalex)
if static_files:
from werkzeug.wsgi import SharedDataMiddleware
application = SharedDataMiddleware(application, static_files)
def inner():
make_server(hostname, port, application, threaded,
processes, request_handler,
passthrough_errors, ssl_context).serve_forever()
if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
display_hostname = hostname != '*' and hostname or 'localhost'
if ':' in display_hostname:
display_hostname = '[%s]' % display_hostname
_log('info', ' * Running on %s://%s:%d/', ssl_context is None
and 'http' or 'https', display_hostname, port)
if use_reloader:
# Create and destroy a socket so that any exceptions are raised before
# we spawn a separate Python interpreter and lose this ability.
test_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
test_socket.bind((hostname, port))
test_socket.close()
run_with_reloader(inner, extra_files, reloader_interval)
else:
inner()
模板渲染
虽然 jinja2 是一个单独的库,但是由于 flask 依赖了jinja2,所以不必单独安装。
python
from flask import render_template
使用
python
@app.route('/template')
def template(): # put application's code here
// 渲染
return render_template('demo.html')
动态渲染
还是使用 jinja2 的 render_template
通过blog_id 与 HTML中 {{ blog_id }} 关联
python
@app.route('/template/blog/<blog_id>')
def template(blog_id): # put application's code here
return render_template('demo.html', blog_id=blog_id)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<a href="www.baidu.com">百度</a>
<div class="header">这里是博客{{ blog_id }}</div>
</body>
</html>
支持其他类型的传参
python
@app.route('/template/blog/<blog_id>')
def template(blog_id): # put application's code here
uesr = User('lijiajun', 'wy15195382735@163.com')
person = {
'username': 'zhangsan',
'email': 'zhangsan的email'
}
return render_template('demo.html', blog_id=blog_id, user=uesr, person=person)
demo.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<a href="www.baidu.com">百度</a>
<div class="header">这里是博客{{ blog_id }}</div>
<div>{{ user }}</div>
<div>{{ user.username }}</div>
<div>{{ user.email }}</div>
<div>{{ person.username }}</div>
<div>{{ user.email }}</div>
</body>
</html>
使用过滤器
使用管道符号 | 即可。 <div>{``{ user.email | length }}</div>
自定义过滤器
python
def filter(value):
return value.upper()
# 增加过滤器
app.add_template_filter(filter, 'filter')
<div>{{ user.email | filter }}</div>
jinja2的语句
html
<div>
{% if age > 18 %}可以进入 {% endif %} {% if age < 18 %} 禁止进入{% endif %}
</div>
html
<div>
{% for foo in age %}
{% endfor %}
</div>
组件传参
demo.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>test</title>
</head>
<body>
<div>
{% extends 'component.html' %} {% block content %} 我是传过来的内容 {%
endblock %} {% block title %} 我是传过来的标题 {% endblock %}
</div>
</body>
</html>
component.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>这是一个组件</title>
</head>
<body>
这是一个组件 {% block title %}{% endblock %} {% block content %}{% endblock
%}
</body>
</html>
加载图片
html
<body>
<div>
<img src='{{ url_for("static",filename="image.png") }}' alt="" />
</div>
</body>
加载Css文件
html
<head>
<meta charset="UTF-8" />
<title>test</title>
<link rel="stylesheet" href='{{ url_for("static",filename="demo.css") }}' />
</head>
加载Js文件
html
<script src='{{ url_for("static",filename="demo.js")}}'></script>
flask 连接 数据库
bash
pip install pymysql
我们不会直接使用这个包去操作数据库,因为需要写原生的SQL语句,我们最好使用 orm。
所以我们还需要下一个:
bash
pip install flask-sqlalchemy
sqlalchemy 给我们提供了 orm 的技术,可以让我们像操作普通对象一样去操作数据库。
这个需要额外安装,因为 flask 没有这个依赖。
python
from flask_sqlalchemy import SQLAlchemy
创建SQLAlchemy实例对象,命名为db,将flask的实例对象app作为参数传给SQLAlchemy,将db和app联系起来,可以调用其相关功能
bash
db = SQLAlchemy(app)
使用gunicorn启动flask
python
gunicorn app:app -c gunicorn.conf.py > gun.log 2>&1 &
一 Gunicorn是基于unix系统,被广泛应用的高性能的Python WSGI HTTP Server。用来解析HTTP请求的网关服务。
它通常是在进行反向代理(如nginx),或者进行负载均衡(如 AWS ELB)和一个web 应用(比如 Django 或者 Flask)之间。
它的运行模型基于pre-fork worker 模型,即就是支持eventlet,也支持greenlet。
二、gunicorn特点
其特点:1、能和大多数的Python Web框架兼容;
2、简单易上手;
3、轻量级的资源消耗;
4、目前,gunicorn只能运行在Linux环境中,不支持windows平台
bash
gunicorn -w 5 -b 0.0.0.0:6000 main:app
解释下参数含义:
-w :表示工作进程数
-b :访问地址和端口
main :flask启动python文件名
app :脚本中创建的Flask对象名
python
from flask import Flask
app = Flask(__name__)
@app.route('/',methods=['GET'])
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=6000)
也可以根据文件启动
bash
gunicorn -c config.py main:app
bash
cat config.py
# 是否开启debug模式
debug = True
# 访问地址
bind = "0.0.0.0:6000"
# 工作进程数
workers = 2
# 工作线程数
threads = 2
# 超时时间
timeout = 600
# 输出日志级别
loglevel = 'debug'
# 存放日志路径
pidfile = "log/gunicorn.pid"
# 存放日志路径
accesslog = "log/access.log"
# 存放日志路径
errorlog = "log/debug.log"
# gunicorn + apscheduler场景下,解决多worker运行定时任务重复执行的问题
preload_app = True
bash
-c CONFIG : CONFIG,配置文件的路径,通过配置文件启动;生产环境使用;
-b ADDRESS : ADDRESS,ip加端口,绑定运行的主机;
-w INT, --workers INT:用于处理工作进程的数量,为正整数,默认为1;
-k STRTING, --worker-class STRTING:要使用的工作模式,默认为sync异步,可以下载eventlet和gevent并指定
--threads INT:处理请求的工作线程数,使用指定数量的线程运行每个worker。为正整数,默认为1。
--worker-connections INT:最大客户端并发数量,默认情况下这个值为1000。
--backlog int:未决连接的最大数量,即等待服务的客户的数量。默认2048个,一般不修改;
-p FILE, --pid FILE:设置pid文件的文件名,如果不设置将不会创建pid文件
--access-logfile FILE : 要写入的访问日志目录
--access-logformat STRING:要写入的访问日志格式
--error-logfile FILE, --log-file FILE : 要写入错误日志的文件目录。
--log-level LEVEL : 错误日志输出等级。
--limit-request-line INT : HTTP请求头的行数的最大大小,此参数用于限制HTTP请求行的允许大小,默认情况下,这个值为4094。值是0~8190的数字。
--limit-request-fields INT : 限制HTTP请求中请求头字段的数量。此字段用于限制请求头字段的数量以防止DDOS攻击,默认情况下,这个值为100,这个值不能超过32768
--limit-request-field-size INT : 限制HTTP请求中请求头的大小,默认情况下这个值为8190字节。值是一个整数或者0,当该值为0时,表示将对请求头大小不做限制
-t INT, --timeout INT:超过这么多秒后工作将被杀掉,并重新启动。一般设定为30秒;
--daemon: 是否以守护进程启动,默认false;
--chdir: 在加载应用程序之前切换目录;
--graceful-timeout INT:默认情况下,这个值为30,在超时(从接收到重启信号开始)之后仍然活着的工作将被强行杀死;一般使用默认;
--keep-alive INT:在keep-alive连接上等待请求的秒数,默认情况下值为2。一般设定在1~5秒之间。
--reload:默认为False。此设置用于开发,每当应用程序发生更改时,都会导致工作重新启动。
--spew:打印服务器执行过的每一条语句,默认False。此选择为原子性的,即要么全部打印,要么全部不打印;
--check-config :显示现在的配置,默认值为False,即显示。
-e ENV, --env ENV: 设置环境变量;