从滴滴到新公司,我用 Django 快速搭了个内部工具站
上周五晚上十点,办公室只剩下我和运维小哥。他一边啃着冷掉的黄焖鸡,一边幽幽地问我:“你那个司机接单统计页面,什么时候能上线?”我盯着屏幕里一堆未读的 Jira 通知,心里一阵发虚——这活儿本来该前端干的,但产品经理说“先做个 MVP 看看效果”,结果前后端全落我头上了。
入职这家新公司才两个月,团队还在磨合期,技术栈五花八门:老系统是 Java Spring Boot,新项目想上 Go,还有几个 Python 爬虫在默默跑着数据。而我,一个刚从滴滴出来、写了四年司机端后端的老码农,突然被拉去搞个内部管理后台——UI 要有,接口要快,还得支持导出 Excel。
思来想去,与其在 Java 里折腾 Thymeleaf 或硬上 React + Spring,不如直接用 Django 搞个全栈方案。毕竟,在滴滴那会儿,我们虽然主力是 Java 微服务,但内部工具、运营平台基本都是 Django 写的——快、稳、省心。
于是,我决定用 Django 搭建我的第一个“正经”Python 网站,并把踩过的坑和最佳实践整理出来。这篇文章不讲 Hello World,只聊真实场景下的快速交付与架构考量。
为什么不是 Java?也不是爬虫?
先澄清一个误区:很多人觉得 Python = 爬虫,Django = 学生玩具。我在滴滴带过实习生,他们一听说用 Python,第一反应就是“是不是要写爬虫抓数据?”——拜托,那是 requests + BeautifulSoup 的活,跟 Web 框架半毛钱关系没有。
至于 Java,它当然强大。我在滴滴司机端的核心订单状态机、计费引擎、推送服务全是 Java 写的,稳定性扛住了双11级别的流量洪峰。但问题是:内部工具不需要高并发,需要的是开发速度。
Django 的优势在于:
- 自带 Admin 后台,5 分钟就能有个 CRUD 界面
- ORM 抽象好,不用手写 SQL(但你知道啥时候该绕过它)
- 中间件机制清晰,适合做权限、日志、审计等横切逻辑
- 部署简单,gunicorn + nginx 套路成熟
更关键的是——我现在重度依赖 ChatGPT 和 Claude 辅助编码。而 Python 的语法简洁,LLM 生成的代码可读性远高于 Java 的样板代码。比如让 Claude 帮我生成一个带分页、搜索、导出的司机列表接口,它三秒就给我 Django View + Serializer + URLconf,我只需要微调字段名。
项目初始化:别再 django-admin startproject 就完了
很多教程教你 django-admin startproject mysite,然后直接 runserver。这在本地跑 demo 没问题,但一到生产环境就翻车。
我在新公司的第一版部署就被运维骂了:“你这 settings.py 里数据库密码是明文?还 commit 到 Git 了?” 当时真的想钻地缝。
正确姿势:
拆分 settings 文件
创建settings/目录,包含:base.py:通用配置local.py:本地开发production.py:线上环境
敏感信息用环境变量
# settings/production.py import os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.getenv('DB_NAME'), 'USER': os.getenv('DB_USER'), 'PASSWORD': os.getenv('DB_PASSWORD'), 'HOST': os.getenv('DB_HOST'), } }用 pydantic 或 django-environ 校验配置
避免线上因少配一个 env 导致 500。静态文件交给 CDN
别指望 Django 自己 serve staticfiles 上生产。用 Whitenoise 开发方便,但正式环境务必配 nginx 或对象存储。
数据库设计:别信 ORM 能解决一切
Django ORM 确实香,.filter().select_related().prefetch_related() 写起来行云流水。但我在滴滴吃过亏——曾经一个司机画像接口,因为没注意 N+1 查询,线上慢到超时,报警响彻凌晨三点。
最佳实践:
- 外键别滥用:内部工具的数据量不大,但关系复杂。比如“司机-车辆-订单-投诉”,如果每个都外键关联,Admin 页面加载会卡死。适当冗余字段(如缓存司机姓名)反而更高效。
- 索引必须显式声明:ORM 不会自动给你加复合索引。比如按城市+状态查询司机,记得:
class Driver(models.Model): city = models.CharField(max_length=20) status = models.CharField(max_length=20) class Meta: indexes = [ models.Index(fields=['city', 'status']), ] - 避免在 Model 里写业务逻辑:把核心逻辑抽到 service 层。这样单元测试好写,也方便未来迁移到其他框架(比如哪天公司又要转 Go)。
接口设计:RESTful 不是唯一答案
很多新人执着于“标准 REST”,非要搞 /drivers/{id}/orders 这种嵌套路由。但在内部工具里,实用主义 > 规范主义。
我的做法:
- 简单 CRUD:用 DRF(Django REST Framework)快速生成 API
- 复杂操作:单独写一个 action view,比如
/api/drivers/bulk-update-status - 导出功能:别返回 JSON,直接返回 CSV 文件流
# views.py
def export_drivers_csv(request):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="drivers.csv"'
writer = csv.writer(response)
writer.writerow(['ID', 'Name', 'City', 'Status'])
for driver in Driver.objects.all():
writer.writerow([driver.id, driver.name, driver.city, driver.status])
return response
测试同学看到这个功能时眼睛都亮了:“终于不用手动复制粘贴 Excel 了!” —— 这就是内部工具的价值。
关于 Windsurf:别被新玩具带偏节奏
最近团队里有人安利 Windsurf(一个新兴的 AI 编程 IDE),说能自动生成整个 Django 项目。我试了试,确实能一键创建带用户认证、Admin、API 的骨架。
但问题来了:它生成的代码不符合团队规范。比如没拆 settings,没加日志中间件,模型没加索引。更糟的是,它默认用 SQLite,而我们生产环境是 PostgreSQL。
所以我的建议是:AI 工具可以加速脚手架搭建,但架构决策不能外包给 LLM。你可以用 Windsurf 生成初稿,但必须人工 review 并重构。就像我刚入职时写的第一个 PR,被 Tech Lead 批了三条:没写 migration 注释、没加 rate limit、没处理空列表边界——这些细节,AI 可不会提醒你。
部署上线:别让运维半夜打电话
Docker 化是底线。哪怕只是个内部工具,也得做到“一次构建,到处运行”。
我的 Dockerfile 精简版:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "mysite.wsgi"]
配合 docker-compose.yml 做本地调试:
version: '3'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DB_HOST=db
depends_on:
- db
db:
image: postgres:14
environment:
POSTGRES_DB: mysite
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
上线前务必检查:
- 是否收集了 static files?(
collectstatic) - 是否执行了 migrations?(别忘了
--no-input) - 日志是否输出到 stdout?(方便 k8s 采集)
总结:Django 不是玩具,是生产力武器
写完这个内部工具,从需求到上线只用了三天。产品经理满意,测试不再抱怨数据导出麻烦,运维也没再半夜 call 我。
回头想想,Django 的真正价值不在于它多“高级”,而在于它让后端开发者能独立交付完整产品。在滴滴时,我们司机端的运营活动页、灰度开关平台、司机申诉审核系统,全是 Django 支撑的。它们不面对 C 端用户,但直接影响业务效率。
所以,如果你是个 Java 后端(像我以前那样),别瞧不起 Python Web 开发。当你需要快速验证想法、搭建内部系统、甚至写个数据可视化面板时,Django + Admin + DRF 的组合拳,可能比 Spring Boot + Vue 快一个数量级。
最后送大家一句我在新公司学到的真理:技术选型不看语言热度,看交付速度和维护成本。
对了,那个司机接单统计页面,现在每天有 200+ 运营在用。而我,终于能在周五晚上准时下班了。

评论 0