3、Flask基础入门:路由与视图函数、请求与响应对象、模板渲染基础、静态文件管理
好,咱们开始聊Flask。说实话,Flask是我个人非常喜欢的一个框架。它轻巧、灵活,特别适合用来搭建法律文书自动生成这类工具。你想想看,法律文书生成的核心逻辑其实就是「输入参数 → 模板填充 → 输出文档」,Flask正好能把这套流程串起来。
这一章,我会带你快速掌握Flask的五个核心概念。别怕,内容不多,但都是实打实能用的。
3.1 路由与视图函数
路由,说白了就是「用户访问哪个网址,服务器执行哪段代码」。在Flask里,我们用@app.route()这个装饰器来定义路由。
举个例子。假设我们要做一个合同生成器,用户访问/contract这个地址时,就返回一份合同模板。代码长这样:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '欢迎使用法律文书自动生成系统'
@app.route('/contract')
def contract():
return '这里将生成合同文书'
嗯,这里要注意:视图函数的名字不能重复,但路由地址可以任意定义。我个人习惯把路由地址和函数名保持一致,这样后期维护时一眼就能看懂。
路由还支持动态参数。比如我们要根据案件编号生成不同的文书:
@app.route('/case/<case_id>')
def case_detail(case_id):
return f'您查询的案件编号是:{case_id}'
我在项目中遇到过一种情况:用户输入的case_id可能包含字母和数字,但有时候我们需要限制格式。Flask提供了转换器,比如<int:case_id>只接收整数。这个细节能帮你省掉不少参数校验的麻烦。
@app.route('/login', methods=['GET', 'POST'])。法律文书系统里,表单提交通常用POST,页面展示用GET。
3.2 请求与响应对象
用户发来的请求,Flask会用request对象来接住。这个对象里装着所有用户传来的信息:表单数据、URL参数、请求头等等。
先看一个获取表单数据的例子:
from flask import request
@app.route('/submit_contract', methods=['POST'])
def submit_contract():
party_a = request.form.get('party_a') # 甲方名称
party_b = request.form.get('party_b') # 乙方名称
return f'合同双方:{party_a} 与 {party_b}'
如果是URL参数(比如/search?keyword=合同),就用request.args.get('keyword')。我曾经踩过一个坑:忘记判断参数是否存在,直接取值导致程序报错。所以建议你养成习惯,用get()方法并设置默认值,比如request.form.get('party_a', '未填写')。
响应对象呢?Flask默认返回字符串,但你可以返回更丰富的内容。比如返回JSON格式的数据,方便前端调用:
from flask import jsonify
@app.route('/api/contract/<int:contract_id>')
def get_contract_api(contract_id):
data = {
'contract_id': contract_id,
'status': '已生成',
'content': '...'
}
return jsonify(data)
你想想看,法律文书系统里,前端和后端经常需要交换数据。用jsonify返回标准JSON,前后端配合起来会非常顺畅。
jsonify会帮你设置正确的Content-Type头,避免一些奇怪的编码问题。
3.3 模板渲染基础
法律文书不能只返回纯文本吧?我们需要漂亮的HTML页面。Flask使用Jinja2模板引擎,简单说就是「在HTML里嵌入Python代码」。
首先,在项目根目录下创建templates文件夹,里面放一个contract.html:
<!DOCTYPE html>
<html>
<head>
<title>合同文书</title>
</head>
<body>
<h1>合同编号:{{ contract_id }}</h1>
<p>甲方:{{ party_a }}</p>
<p>乙方:{{ party_b }}</p>
<p>签署日期:{{ date }}</p>
</body>
</html>
然后在视图函数里渲染它:
from flask import render_template
@app.route('/contract/<int:contract_id>')
def show_contract(contract_id):
return render_template('contract.html',
contract_id=contract_id,
party_a='张三',
party_b='李四',
date='2025-01-15')
这里{{ }}是变量占位符,Jinja2会自动替换成真实数据。我还用过{% %}做循环和判断,比如生成多条条款时:
<ul>
{% for clause in clauses %}
<li>第{{ loop.index }}条:{{ clause }}</li>
{% endfor %}
</ul>
我个人觉得,模板渲染是法律文书自动生成的核心。你把文书模板写好,把变量位置留好,后端一填充,一份完整的文书就出来了。效率比手动复制粘贴高太多了。
3.4 静态文件管理
文书页面需要样式吧?需要图片吧?这些都属于静态文件。Flask默认在static文件夹里找它们。
项目结构大概是这样的:
your_project/
├── app.py
├── templates/
│ └── contract.html
└── static/
├── css/
│ └── style.css
├── js/
│ └── main.js
└── images/
└── logo.png
在模板里引用静态文件,要用url_for函数:
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="logo">
为什么不用直接写路径?因为url_for会自动处理路径问题,就算你以后改了静态文件的存放位置,代码也不用大改。我在一个旧项目里吃过亏,直接写死了路径,后来迁移服务器时改得想哭。
3.5 本章知识体系
下面这张图,是我梳理的Flask基础核心逻辑。你看一遍,应该能对整体有个把握。
这张图展示了用户请求的完整流程。从请求进来,到路由匹配,再到视图函数处理,最后返回响应。其中视图函数可以调用request对象获取数据,也可以渲染模板,还可以引用静态文件。说白了,Flask就是帮你把这一套流程管得明明白白。
好了,这一章的内容就到这里。你先把路由、请求响应、模板渲染、静态文件这四个点吃透,后面搭建法律文书系统时,你会发现这些基础操作会反复用到。嗯,下一章我们聊点更实战的东西。