当前位置: 首页 > news >正文

初识Flask框架

目录

一、Flask 框架概述:轻量级 Web 开发的首选工具

1.1 Flask 的诞生与定位

1.2 核心依赖:Werkzeug 与 Jinja2

1.3 为什么选3择 Flask?

二、快速入门:从16环境搭建到第一个 Flask 应用

2.1 环境准备

2.1.1 安装 Python

2.1.2 安装 Flask

2.2 创建第一4个 Flask 应用:Hello World

2.2.1 代码实现

2.2.2 运7行与验证

三、核心功能详解8:路由、视图与模板渲染

3.1 路由系统:URL 与视图函数的映射

3.1.1 静态路由

3.1.2 动态路由:捕获 URL 中的参数

动态参数类型9限制

3.1.3 支持多种 HTTP 请求方法

3.2 模板引10擎 Jinja2:动态生成 HTML 页面

3.2.1 模板基础:变量与表达式

3.2.2 控11制结构:条件与循环

条件判断

循环遍历

3.2.3 模17板继承:复用布局与代码

基础模板 base.html

子模板 index.html

四、表单处理与数12据验证:构建交互式 Web 应用

4.1 使用 Flask-WTF 简化表单开发

4.1.1 安装 Flask-WTF

4.1.2 创建表单类

4.2 表单渲染13与处理流程

4.2.1 视图函数处理表单

4.2.2 模14板中渲染表单

五、项目结构与部署:从开发到生产环境

5.3.1 选择 Web 服务器

六、扩展应用场景:打造功能完善的 Flask 应用

6.1 数据库集成:使用 SQLAlchemy 操作数据库

6.1.1 安装与初始化

6.1.2 定义数据模型

6.1.3 数据库操作示例

6.2 身份认证:使用 Flask-Login 实现用户登录系统

6.2.1 安装与配置

6.2.2 视图函数与模板

6.3 接口开发:构建 RESTful API

6.3.1 安装扩展

6.3.2 创建 API 资源

七、实战案例:优化简单博客应用

7.1 需求分析

7.2 改进后的项目结构

7.3 核心功能实现

7.3.1 用户注册表单

7.3.2 文章分类模型

7.3.3 评论功能

7.3.4 分页显示文章

八、性能优化与最佳实践

8.1 缓存机制

8.1.1 页面缓存

8.1.2 数据库查询缓存

8.2 异步任务处理

8.3 代码规范与调试技巧

8.3.1 代码规范

8.3.2 调试技巧

九、总结与展望

9.1 Flask 的适用场景总结


一、Flask 框架概述:轻量级 Web 开发的首选工具

1.1 Flask 的诞生与定位

Flask 诞生于 2010 年,由开发者 Armin Ronacher 基于 Python 语言开发。作为一款 “微框架”,它的设计理念聚焦于简洁性灵活性。这里的 “微” 并非指功能薄弱,而是强调核心功能精简,仅提供构建 Web 应用必需的基础工具(如路由、请求处理、模板引擎),同时允许开发者根据项目需求自由选择扩展库,避免了传统重型框架(如 Django)对项目结构和开发流程的强制约束。

这种定位使 Flask 1具备极强的适应性:

  • 适合场景:快速原型开发、中小型 Web 应用(如博客、API 接口、企业内部系统)、数据科学项目的 Web 化展示等。
  • 不适合场景:超大型企业级应用(需复杂的权限系统、ORM 模型等内置功能时,可考虑 Django)。

1.2 核心依赖:Werkzeug 与 Jinja2

Flask 的运行依赖两个关键 Python 库:

Werkzeug
作为 Flask 的底层库,它实现了 WSGI(Web 服务器网关接口)标准,负责处理 HTTP 请求与响应、路由匹配、请求解析等核心功能。例如,当浏览器发送一个请求到服务器时,Werkzeug 会解析请求的 URL、方法、参数等信息,并将其传递给 Flask 应用的路由处理函数。

*Jinja22*
这是一款高性能的模板引擎,用于动态生成 HTML 页面。它支持变量渲染、条件判断、循环语句等功能,允许开发者将 Python 数据与 HTML 结构分离,提升代码的可维护性。例如,通过 {{ variable }} 语法,可将 Python 变量插入到 HTML 中动态展示。

1.3 为什么选3择 Flask?

  • 学习门槛低:核心概念简洁,初学者可快速上手,无需深入理解复杂的框架设计模式。
  • 灵活性高:无强制项目结构,可根据需求自由扩展(如选择数据库框架 SQLAlchemy、表单处理扩展 Flask-WTF 等)。
  • 社区生态丰富:拥有大量高质量扩展库,覆盖身份认证、数据库操作、缓存管理等开发场景。
  • 部署友好:可轻松部署到云服务器、Docker 容器等环境,支持与 Nginx、Gunicorn 等生产级服务器配合使用。

二、快速入门:从16环境搭建到第一个 Flask 应用

2.1 环境准备

2.1.1 安装 Python

Flask 基于 Python 开发,需先安装 Python 3.6 及以上版本。安装完成后,可通过以下命令验证:

python --version  # 查看 Python 版本
pip --version     # 查看 pip 包管理工具版本
2.1.2 安装 Flask

使用 pip 命令快速安装:

pip install flask

安装完成后,即可开始创建 Flask 应用。

2.2 创建第一4个 Flask 应用:Hello World

2.2.1 代码实现

新建一个 Python 文件 app.py,输入以下代码:

from flask import Flask# 创建 Flask 应用实例,__name__ 表示当前模块名
app = Flask(__name__)# 定义路由:当访问根路径时,执行 hello_world 函数
@app.route('/')
def hello_world():return 'Hello, World!'# 启动应用,debug=True 表示开启调试模式
if __name__ == '__main__':app.run(debug=True)

代码解析:

Flask(__name__)__name__ 参数用于帮助 Flask 确定应用的根路径,以便正确加载静态文件和模板文件。

@app.route{insert\_element\_5\_}('/'):路由装饰器,将根路径 '/' 与视图函数 hello_world 绑定。当用户访问该 URL 时,Flask 会调用该函数并返回响应。

app.run()6:启动开发服务器,默认监听本地地址 127.0.0.1:5000debug=True 开启调试模式,支持代码修改后自动重启应用,并在出错时显示详细错误信息,方便开发。

2.2.2 运7行与验证

在命令行中执行以下命令启动应用:

python app.py

打开浏览器访问 http://127.0.0.1:5000/,页面将显示 Hello, World!,表明应用运行成功。

三、核心功能详解8:路由、视图与模板渲染

3.1 路由系统:URL 与视图函数的映射

路由是 Flask 的核心功能之一,它决定了不同 URL 对应的处理逻辑。Flask 通过 @app.route 装饰器定义路由规则,支持静态路由、动态路由和多种 HTTP 请求方法。

3.1.1 静态路由

最简单的路由形式,用于匹配固定 URL。例如:

@app.route('/about')
def about():return 'This is the about page.'

访问 http://localhost:5000/about 时,将显示 This is the about page.

3.1.2 动态路由:捕获 URL 中的参数

通过在 URL 中使用 <参数名> 语法,可捕获动态参数并传递给视图函数。例如:

@app.route('/greet/<name>')
def greet(name):return f'Hello, {name}!'

当访问 http://localhost:5000/greet/John 时,name 参数的值为 'John',响应为 'Hello, John!'

动态参数类型9限制

默认情况下,参数类型为字符串。若需指定类型,可使用 <类型:参数名> 格式,支持的类型包括:

string(默认,字符串)

int(整数)

float(浮点数)

path(包含斜杠的字符串)

uuid(UUID 格式字符串)

示例:

@app.route('/user/<int:user_id>')
def get_user(user_id):return f'User ID: {user_id}, Type: {type(user_id)}'

访问 http://localhost:5000/user/123 时,user_id 为整数 123,响应为 'User ID: 123, Type: <class \'int\'>'

3.1.3 支持多种 HTTP 请求方法

Flask 默认支持 GET 请求,若需处理 POST、PUT、DELETE 等方法,需通过 methods 参数指定。例如,处理表单提交的 POST 请求:

from flask import request@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form.get('username')password = request.form.get('password')# 执行登录逻辑if username == 'admin' and password == '123456':return 'Login successful!'else:return 'Login failed.'else:return 'This is the login page.'

若用户通过 GET 请求访问 /login,显示登录页面;通过 POST 请求提交表单时,验证用户名和密码并返回结果。

3.2 模板引10擎 Jinja2:动态生成 HTML 页面

3.2.1 模板基础:变量与表达式

Jinja2 模板通过 {{ }} 语法渲染 Python 变量和表达式。例如,创建模板文件 templates/greet.html

<!DOCTYPE html>
<html>
<head><title>Welcome</title>
</head>
<body><h1>Hello, {{ name }}!</h1><p>Today's date: {{ current_time }}</p>
</body>
</html>

在视图函数中使用 render_template 函数渲染模板并传递数据:

from flask import render_template
from datetime import datetime@app.route('/greet/<name>')
def greet(name):current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')return render_template('greet.html', name=name, current_time=current_time)

访问该路由时,模板中的 {{ name }} 和 {{ current_time }} 会被替换为实际传递的值。

3.2.2 控11制结构:条件与循环

Jinja2 支持 {% %} 语法的控制结构,如 if 条件判断和 for 循环。

条件判断
{% if user.is_authenticated %}<p>Welcome back, {{ user.username }}!</p>
{% else %}<p><a href="/login">Please log in</a></p>
{% endif %}
循环遍历

假设视图函数传递一个 posts 列表(包含文章标题和内容):

<ul>{% for post in posts %}<li><h3>{{ post.title }}</h3><p>{{ post.content }}</p></li>{% endfor %}
</ul>

循环会遍历 posts 列表,为每个元素生成一个 <li> 标签。

3.2.3 模17板继承:复用布局与代码

通过模板继承机制,可定义基础模板(包含通用布局),子模板继承基础模板并覆盖特定块(Block)。

基础模板 base.html
<!DOCTYPE html>
<html>
<head><title>{% block title %}My Website{% endblock %}</title><link rel="stylesheet" href="/static/css/style.css">
</head>
<body><header><h1>Flask Blog</h1></header><main>{% block content %}{% endblock %}</main><footer><p>&copy; {{ current_year }} Flask Demo</p></footer>
</body>
</html>

{% block title %} 和 {% block content %} 定义了可被覆盖的块。

子模板 index.html
{% extends "base.html" %}{% block title %}Home{% endblock %}{% block content %}<h2>Welcome to the Homepage</h2><p>This is the main content area.</p>
{% endblock %}

{% extends "base.html" %} 声明继承基础模板,{% block %} 标签覆盖对应的块内容。

四、表单处理与数12据验证:构建交互式 Web 应用

4.1 使用 Flask-WTF 简化表单开发

Flask-WTF 是 Flask 的表单处理扩展,提供了表单类定义、字段验证、CSRF 保护等功能,避免手动编写 HTML 表单和验证逻辑的繁琐过程。

4.1.1 安装 Flask-WTF
pip install flask-wtf
4.1.2 创建表单类

在 forms.py 中定义表单类,继承自 FlaskForm,并声明字段和验证规则:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Emailclass LoginForm(FlaskForm):email = StringField('Email', validators=[DataRequired(), Email()])password = PasswordField('Password', validators=[DataRequired(), Length(min=6)])submit = SubmitField('Login')

StringField:文本输入字段,PasswordField 为密码输入字段。

validators:验证器列表,DataRequired() 确保字段不为空,Email() 验证邮箱格式,Length(min=6) 限制密码长度至少 6 位。

4.2 表单渲染13与处理流程

4.2.1 视图函数处理表单

在路由中实例化表单类,判断表单是否提交并通过验证:

from flask import render_template, request
from forms import LoginForm@app.route('/login', methods=['GET', 'POST'])
def login():form = LoginForm()if form.validate_on_submit():# 表单验证通过,获取字段值email = form.email.datapassword = form.password.data# 执行登录逻辑(如查询数据库)return f'Login successful for {email}!'# GET 请求或验证失败,渲染登录页面return render_template('login.html', form=form)

form.validate_on_submit() 方法在表单提交且所有字段验证通过时返回 True

4.2.2 模14板中渲染表单

在 login.html 中使用 Jinja2 语法渲染表单字段,并自动生成 CSRF 令牌:

<form method="POST">{{ form.hidden_tag() }}  <!-- 自动生成 CSRF 令牌 --><div><label for="email">Email:</label>{{ form.email(size=32) }}{% if form.email.errors %}<span class="error">{{ form.email.errors[0] }}</span>{% endif %}</div><div><label for="password">Password:</label>{{ form.password(size=32) }}{% if form.password.errors %}<span class="error">{{ form.password.errors[0] }}</span>{% endif %}</div><button type="submit">{{ form.submit.label }}</button>
</form>

{{ form.hidden_tag() }}:生成 CSRF 保护的隐藏字段,防止跨站请求伪造。

form.field{insert\_element\_16\_}_name:渲染字段的 HTML 标签,field_name.errors 显示验证错误信息。

五、项目结构与部署:从开发到生产环境

5.3.1 选择 Web 服务器
  1. Gunicorn
    基于 WSGI 的 HTTP 服务器,适合与 Flask 配合使用。安装命令:
    pip install gunicorn
    

    启动命令(假设应用实例在 app 模块的 app 变量中):
    gunicorn -w 4 -b 0.0.0.0:5000 app:app
    
     
    • -w 4

六、扩展应用场景:打造功能完善的 Flask 应用

6.1 数据库集成:使用 SQLAlchemy 操作数据库

Flask-SQLAlchemy 是 Flask 的 SQLAlchemy 扩展,简化数据库操作。

6.1.1 安装与初始化
pip install flask-sqlalchemy

在 app/__init__.py 中配置数据库:

运行

from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'  # 使用 SQLite 数据库
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
6.1.2 定义数据模型

在 app/models.py 中创建用户和文章模型:

运行

from app import db
from datetime import datetimeclass User(db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(80), unique=True, nullable=False)email = db.Column(db.String(120), unique=True, nullable=False)posts = db.relationship('Post', backref='author', lazy=True)class Post(db.Model):id = db.Column(db.Integer, primary_key=True)title = db.Column(db.String(100), nullable=False)content = db.Column(db.Text, nullable=False)created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
6.1.3 数据库操作示例

运行

# 创建所有表
with app.app_context():db.create_all()# 添加用户
user = User(username='john', email='john@example.com')
db.session.add(user)
db.session.commit()# 查询所有文章
posts = Post.query.order_by(Post.created_at.desc()).all()

6.2 身份认证:使用 Flask-Login 实现用户登录系统

Flask-Login 提供了用户认证的核心功能,如会话管理、登录状态判断等。

6.2.1 安装与配置
pip install flask-login

在 app/__init__.py 中初始化扩展:

运行

from flask_login import LoginManagerlogin_manager = LoginManager(app)
login_manager.login_view = 'login'  # 指定未登录时跳转的路由# 加载用户回调函数
@login_manager.user_loader
def load_user(user_id):return User.query.get(int(user_id))
6.2.2 视图函数与模板

修改登录路由,使用 login_user 函数登录用户:

运行

from flask_login import login_user, current_user, login_required@app.route('/login', methods=['GET', 'POST'])
def login():if current_user.is_authenticated:return redirect(url_for('index'))form = LoginForm()if form.validate_on_submit():user = User.query.filter_by(email=form.email.data).first()if user and check_password_hash(user.password, form.password.data):login_user(user, remember=form.remember.data)return redirect(url_for('index'))return 'Invalid email or password.'return render_template('login.html', form=form)

在模板中通过 current_user 判断登录状态:

预览

{% if current_user.is_authenticated %}<a href="/logout">Logout</a>
{% else %}<a href="/login">Login</a>
{% endif %}

6.3 接口开发:构建 RESTful API

Flask 可轻松开发 RESTful API,配合 flask-restful 扩展可进一步简化流程。

6.3.1 安装扩展
pip install flask-restful
6.3.2 创建 API 资源

运行

from flask_restful import Api, Resource, reqparse
from app.models import Postapi = Api(app)# 请求解析器:验证请求参数
post_parser = reqparse.RequestParser()
post_parser.add_argument('title', type=str, required=True, help='Title is required')
post_parser.add_argument('content', type=str, required=True, help='Content is required')class PostResource(Resource):def get(self, post_id):post = Post.query.get_or_404(post_id)return {'id': post.id, 'title': post.title, 'content': post.content}def delete(self, post_id):post = Post.query.get_or_404(post_id)db.session.delete(post)db.session.commit()return {'message': 'Post deleted successfully'}, 204class PostListResource(Resource):def get(self):posts = Post.query.all()return [{'id': p.id, 'title': p.title} for p in posts]def post(self):args = post_parser.parse_args()post = Post(title=args['title'], content=args['content'], user_id=current_user.id)db.session.add(post)db.session.commit()return {'id': post.id, 'title': post.title}, 201api.add_resource(PostListResource, '/api/posts')
api.add_resource(PostResource, '/api/posts/<int:post_id>')

通过 curl 命令测试 API:

# 获取所有文章
curl http://localhost:5000/api/posts# 创建新文章
curl -X POST -H "Content-Type: application/json" -d '{"title":"New Post", "content":"Hello API!"}' http://localhost:5000/api/posts

七、实战案例:优化简单博客应用

7.1 需求分析

在文档提供的简单博客基础上,增加以下功能:

  • 用户注册与登录系统
  • 文章分类与标签
  • 评论功能
  • 分页显示文章列表

7.2 改进后的项目结构

simple_blog/
├── app/
│   ├── __init__.py
│   ├── routes.py        # 包含 Web 路由和 API 路由
│   ├── forms.py         # 注册/登录表单、文章表单
│   ├── models.py        # 用户、文章、分类、评论模型
│   ├── templates/
│   │   ├── base.html    # 基础模板
│   │   ├── index.html   # 首页(文章列表)
│   │   ├── login.html   # 登录页面
│   │   └── post.html    # 文章详情页
│   └── static/
├── migrations/          # 数据库迁移文件(使用 Alembic)
├── venv/
└── requirements.txt

7.3 核心功能实现

7.3.1 用户注册表单

在 forms.py 中添加注册表单:

运行

class RegisterForm(FlaskForm):username = StringField('Username', validators=[DataRequired(), Length(min=4, max=20)])email = StringField('Email', validators=[DataRequired(), Email()])password = PasswordField('Password', validators=[DataRequired(), Length(min=6)])confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])submit = SubmitField('Register')
7.3.2 文章分类模型

在 models.py 中定义分类与文章的关联:

运行

class Category(db.Model):id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(50), nullable=False)posts = db.relationship('Post', backref='category', lazy=True)

创建文章时指定分类:

运行

category = Category.query.filter_by(name='Tech').first()
post = Post(title='Flask API Guide', content='...', category=category, author=current_user)
7.3.3 评论功能

定义评论模型,与用户和文章建立关联:

运行

class Comment(db.Model):id = db.Column(db.Integer, primary_key=True)content = db.Column(db.Text, nullable=False)created_at = db.Column(db.DateTime, default=datetime.utcnow)user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)user = db.relationship('User', backref=db.backref('comments', lazy=True))

在文章详情页模板中渲染评论列表:

预览

<h3>Comments:</h3>
<ul>{% for comment in post.comments %}<li><strong>{{ comment.user.username }}:</strong> {{ comment.content }}</li>{% endfor %}
</ul>
7.3.4 分页显示文章

使用 paginate 方法实现分页:

运行

@app.route('/')
def index():page = request.args.get('page', 1, type=int)posts = Post.query.order_by(Post.created_at.desc()).paginate(page=page, per_page=5, error_out=False)return render_template('index.html', posts=posts.items, pagination=posts)

模板中生成分页链接:

预览

<div class="pagination">{% if pagination.has_prev %}<a href="?page={{ pagination.prev_num }}">Previous</a>{% else %}<span class="disabled">Previous</span>{% endif %}<span class="current">Page {{ pagination.page }} of {{ pagination.pages }}</span>{% if pagination.has_next %}<a href="?page={{ pagination.next_num }}">Next</a>{% else %}<span class="disabled">Next</span>{% endif %}
</div>

八、性能优化与最佳实践

8.1 缓存机制

8.1.1 页面缓存

使用 flask-caching 扩展缓存动态页面:

pip install flask-caching

运行

from flask_caching import Cachecache = Cache(app, config={'CACHE_TYPE': 'SimpleCache'})@app.route('/')
@cache.cached(timeout=300)  # 缓存 5 分钟
def index():# 复杂数据查询逻辑return render_template('index.html', posts=posts)
8.1.2 数据库查询缓存

对频繁查询的数据库结果进行缓存:

运行

@cache.memoize(timeout=3600)
def get_popular_posts():return Post.query.order_by(Post.views.desc()).limit(10).all()

8.2 异步任务处理

使用 Celery 处理耗时任务(如发送邮件、生成报表),避免阻塞主线程:

pip install celery

运行

# 创建 Celery 实例
celery = Celery(app.name, broker='redis://localhost:6379/0')
celery.conf.update(app.config)# 异步任务示例:发送邮件
@celery.task
def send_email_async(to, subject, body):# 发送邮件逻辑pass# 在视图函数中调用异步任务
send_email_async.delay('user@example.com', 'Welcome', 'Hello from Flask!')

8.3 代码规范与调试技巧

8.3.1 代码规范
  • 使用虚拟环境隔离项目依赖(python -m venv venv)。
  • 遵循 PEP 8 代码风格,合理使用空行、缩进和注释。
  • 模块化开发,避免将所有代码写入单个文件。
8.3.2 调试技巧
  • 开发阶段启用 debug=True,利用错误页面快速定位问题。
  • 使用 print() 或 logging 模块输出调试信息:

    python

    运行

    import logging
    app.logger.info('User logged in: %s', current_user.username)
    

  • 运行

    from pdb import set_trace; set_trace()  # 在代码中插入断点
    

    九、总结与展望

9.1 Flask 的适用场景总结

  • 小型项目与原型开发:快速搭建 MVP(最小可行产品),验证业务逻辑。
  • API 服务开发:轻量级设计适合构建 RESTful API,供移动端或前端应用调用。
  • 数据科学与机器学习部署:将模型封装为 Flask API,方便与 Web 系统集成。
  • 需要高度定制化的项目:灵活的扩展机制允许开发者按需选择工具链,避免框架过度设计。
http://www.xdnf.cn/news/603289.html

相关文章:

  • 取消 Conda 默认进入 Base 环境
  • Windows 安装 FFmpeg 新手教程(附环境变量配置)
  • 大模型部署ollama/vLLM/LMDeploy/SGLang区别
  • 一个C#跨平台的机器视觉和机器学习的开源库
  • Honeywell 05701-A-0302 单通道控制卡
  • 基于DPABI提取nii文件模板的中心点坐标
  • 【论文阅读】LLaVA-OneVision: Easy Visual Task Transfer
  • vscode里几种程序调试配置
  • WebGL入门:贴图
  • iOS 主要版本发布历史
  • Spark on Yarn 高可用模式部署流程
  • 卷积神经网络(CNN)可视化技术详解:从特征学到演化分析
  • 单点击登录sso实现
  • Android Studio历史版本下载方法
  • SpringBoot3整合WebSocket
  • LIEDNet: A Lightweight Network for Low-light Enhancement and Deblurring论文阅读
  • 探索Dify:开启大语言模型应用开发新时代
  • 怎么判断一个Android APP使用了Cordova这个跨端框架
  • [SWPUCTF 2024 秋季新生赛]ret2libc也阴嘛?(NSSCTF)
  • OpenEuler-Apache服务原理
  • 如何配置jmeter做分布式压测
  • .jsx文件和.tsx文件有什么区别
  • 补题目找规律
  • uni-app/vue2:微信小程序实现文件流的下载及预览
  • Claude MCP协议从入门到精通
  • 【Hexo】2.常用的几个命令
  • MySQL别名规则与应用场景
  • Facebook + AdsPower!用一台设备实现 Facebook 多账号管理
  • Jenkins 构建日志统一上报:企业级 DevOps 管理实践
  • 科学养生:解锁现代健康生活新方式