在智能合同审查系统的开发演进过程中,我们经历了一次重要的架构转型:从传统的 Django 模版系统(MVT)迁移到了前后端分离的 API 驱动架构(Django REST Framework + Vue 3)。
这一转变并非盲目跟风,而是为了解决我们在初期开发中遇到的三个核心痛点。本文将结合具体的代码示例,详细对比这两种实现方式,并阐述重构带来的收益。
1. 我们面临的三个核心问题
在项目初期,我们使用了 Django 原生的模版系统。随着业务复杂度的增加,以下问题日益凸显:
耦合度高:前端页面逻辑(HTML/CSS/JS)与后端业务逻辑(Python View)紧密缠绕。修改一个按钮的样式,可能需要后端开发人员介入修改模版文件;后端修改数据结构,又极易打破前端的渲染逻辑。 交互体验差:传统的 Web 应用是多页应用(MPA)。用户每次点击'下一页'、提交表单或进行筛选,浏览器都需要向服务器请求完整的 HTML 页面并重新加载。这种'白屏 - 加载 - 渲染'的循环无法提供类似原生应用的流畅体验。 接口复用难:模版系统直接返回渲染好的 HTML 字符串。如果未来我们需要开发移动端 App 或微信小程序,现有的视图逻辑完全无法复用,必须重新开发一套返回 JSON 数据的 API。
2. 场景实战:合同列表展示
为了更直观地说明区别,我们以'获取并展示用户合同列表'这一高频场景为例,分别展示两种架构下的代码实现。
2.1 传统 Django 模版系统实现
在传统模式下,后端 View 负责查询数据并将其'填'入 HTML 模版中,浏览器接收到的是最终的 HTML 页面。
后端视图 (Views.py)
# 传统 Django View
from django.shortcuts import render
from .models import Contract
def contract_list(request):
# 1. 业务逻辑:查询当前用户的未删除合同
contracts = Contract.objects.filter(
uploader=request.user,
is_deleted=False
).order_by('-created_at')
context = {
'contracts': contracts,
'username': request.user.username
}
# 2. 渲染:将数据与 HTML 模版混合,返回完整的 HTML 页面
return render(request, 'contract/contract_list.html', context)
前端模版 (contract_list.html)
<!-- Django Template Language (DTL) -->
{% extends "base.html" %}
{% block content %}
<div>
<h2>{{ username }} 的合同列表</>
合同编号
合同名称
状态
操作
{% for contract in contracts %}
{{ contract.contract_no }}
{{ contract.name }}
{{ contract.get_status_display }}
查看
{% empty %}
暂无合同
{% endfor %}
{% endblock %}


