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>只接收整数。这个细节能帮你省掉不少参数校验的麻烦。

小技巧: 如果你想让路由支持多种HTTP方法(比如GET和POST),可以这样写:@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,前后端配合起来会非常顺畅。

注意: 千万别直接返回Python字典!Flask虽然能自动转换,但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会自动处理路径问题,就算你以后改了静态文件的存放位置,代码也不用大改。我在一个旧项目里吃过亏,直接写死了路径,后来迁移服务器时改得想哭。

建议: 法律文书系统里,可以把法院的印章图片、文书模板的CSS样式都放在static文件夹里。这样页面加载快,管理也方便。

3.5 本章知识体系

下面这张图,是我梳理的Flask基础核心逻辑。你看一遍,应该能对整体有个把握。

Flask基础核心逻辑 用户请求 路由匹配 视图函数 响应 request 对象(表单/参数) render_template 模板渲染 静态文件(CSS/JS/图片) 用户请求 → 路由匹配 → 视图函数处理 → 返回响应(模板/JSON/静态文件)

这张图展示了用户请求的完整流程。从请求进来,到路由匹配,再到视图函数处理,最后返回响应。其中视图函数可以调用request对象获取数据,也可以渲染模板,还可以引用静态文件。说白了,Flask就是帮你把这一套流程管得明明白白。

好了,这一章的内容就到这里。你先把路由、请求响应、模板渲染、静态文件这四个点吃透,后面搭建法律文书系统时,你会发现这些基础操作会反复用到。嗯,下一章我们聊点更实战的东西。


专注资料整理