从 Vue 切到 Django:一个前端仔的 Python 全栈初体验
上周五晚上十点半,我正一边啃着老妈寄来的郫县豆瓣酱拌面(成都人下班后的深夜治愈神器),一边在 VSCode 里调一个 Vue3 的响应式边界 case。突然微信“叮”一声——是我们组后端大佬老张:
“小陈,你不是最近在搞 Node.js 吗?那正好,下周有个内部工具要上线,用 Python 写个简单后台,Django 框架,三天能搞定不?”
我一口面差点喷出来。
Django?Python?我连 virtualenv 都没装过!
但嘴比脑子快:“没问题啊,包在我身上!”
——典型的程序员“答应时爽,写代码时哭”综合征。
说来也巧。其实我早就想试试 Python 的 Web 开发了。毕竟每天看隔壁 Java 组同事动不动就在群里讨论“Spring Boot 自动装配原理”、“MyBatis 二级缓存失效场景”,甚至还有人在准备跳槽时疯狂刷《Java 面试题大全》。而我呢?除了 fetch 和 axios,连数据库连接池都没见过几次。
作为纯前端出身、最近才开始学 Node.js 的“伪全栈”,这次被逼上梁山,干脆就借机深入体验一把 Django ——这个传说中“开箱即用”的 Python Web 框架。
为什么是 Django?而不是 FastAPI 或 Flask?
说实话,一开始我是想直接上 FastAPI 的(毕竟文档酷炫,TypeScript 转过来毫无违和感)。但老张一句话打消了我的幻想:
“这工具后面要接 Admin 后台,还要快速出表单,Django 自带 ORM + Admin + 用户系统,一天就能跑起来。你用 FastAPI?光配个登录验证就得两天。”
行吧,有道理。而且我翻了翻公司内部几个老项目的 Git 记录,发现不少运维监控平台、数据录入工具都是 Django 写的——稳定、省事、适合内部系统。
再加上我最近还在偷偷学 Rust(别问,问就是“技术前瞻性”),时间本来就紧,Django 这种“约定优于配置”的风格,反而能让我少纠结架构,多交差。
环境搭建:从“pip not found”开始的血泪史
作为一个常年只用 npm install 的前端仔,第一次面对 Python 环境管理,真的有点懵。
我打开终端,自信地敲:
pip install django
结果:
-bash: pip: command not found
……好家伙,Mac 自带的 Python 是 2.7,而我之前为了跑某个脚本装过 pyenv,结果 PATH 全乱了。折腾半小时后,终于用 Homebrew 装了 Python 3.11,并创建了虚拟环境:
brew install python@3.11
python3 -m venv mysite_env
source mysite_env/bin/activate
pip install django
💡 小贴士:前端同学习惯
node_modules,但 Python 的虚拟环境更像“隔离沙箱”。建议每个项目都单独建一个,避免依赖冲突——这点比 npm clean 得多。
确认安装成功:
django-admin --version
# 输出 4.2.x,搞定!
然后一键生成项目骨架:
django-admin startproject mysite
cd mysite
python manage.py runserver
浏览器打开 http://127.0.0.1:8000,熟悉的火箭图标出现——It worked! 那一刻,我仿佛回到了第一次 create-react-app 成功运行的感动。
创建第一个 App:不是 Application,是模块!
Django 里的 “App” 不是指整个网站,而是功能模块。比如用户系统、博客、订单,各自是一个 App。
我需要做个简单的任务管理工具,于是:
python manage.py startapp tasks
然后在 mysite/settings.py 里注册它:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
# ... 其他默认项
'tasks', # ← 加这一行
]
这时候我突然想到:这不就像 Vue 里注册组件吗? 只不过这里是全局注册,不能按需引入(笑)。
数据模型:ORM 让我忘了 SQL
作为前端,我对数据库一直有种敬畏感。以前用 Node.js + MongoDB,靠 Mongoose 勉强糊弄;但关系型数据库?光是外键、索引、事务这些词就让我头大。
结果 Django 的 ORM 直接给我上了一课。
我在 tasks/models.py 里定义了一个任务模型:
from django.db import models
from django.contrib.auth.models import User
class Task(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(blank=True)
completed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
是不是很像 TypeScript interface?但比 interface 强大多了——这直接对应数据库表结构!
执行迁移:
python manage.py makemigrations
python manage.py migrate
Django 自动生成 SQL 并执行,连 SQLite 都不用我手动建。那一刻我惊了:这不比写 CREATE TABLE 省事一万倍?
🤔 对比 Java:在 Java 世界里,你得写 Entity + Repository + Service + Controller,还得配 MyBatis XML 或 JPA 注解。而 Django 一个 model 文件搞定 80%。
后台管理界面:Admin 系统是神!
最让我震撼的是 Django 自带的 Admin 后台。
只需两步:
- 创建超级用户:
python manage.py createsuperuser - 在
tasks/admin.py注册模型:
from django.contrib import admin
from .models import Task
admin.site.register(Task)
然后访问 /admin,登录后——boom!一个完整 CRUD 界面直接可用!
能增删改查、支持搜索、过滤、分页,连外键关联都自动变成下拉框。我试了试添加几个任务,数据实时进数据库。
这时候我忍不住发了个朋友圈:“Django Admin 是不是偷看了我的需求文档?”
评论区立刻有 Java 同事酸了:“我们组光是为了搭个后台管理,前后端联调三天,还被产品经理骂样式丑。”
而我?零前端代码,纯后端配置,直接交付。
视图与模板:回到“服务端渲染”的年代
虽然现在主流是前后端分离,但 Django 默认用 服务端渲染(SSR)。这对前端出身的我来说,既熟悉又陌生。
我在 tasks/views.py 写了个简单视图:
from django.shortcuts import render
from .models import Task
def task_list(request):
tasks = Task.objects.filter(owner=request.user)
return render(request, 'tasks/list.html', {'tasks': tasks})
然后在 tasks/templates/tasks/list.html 写模板:
<!-- 注意:Django 模板语法,不是 JSX! -->
<h1>我的任务</h1>
<ul>
{% for task in tasks %}
<li>
<input type="checkbox" {% if task.completed %}checked{% endif %}>
{{ task.title }}
</li>
{% endfor %}
</ul>
路由配置在 tasks/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.task_list, name='task_list'),
]
再在主 urls.py include 进去。
跑起来,登录后就能看到任务列表了。
但问题来了:这交互也太原始了吧?
我想加个“点击完成”功能,总不能每次点完都刷新页面吧?这时候我陷入了纠结:
- 继续用 Django 模板 + 表单提交?用户体验差。
- 还是改成 API + Vue 前端?但工期只有三天!
最后我折中:用 HTMX!(别笑,真香)
不过那是后话了。至少第一天,我已经有了一个能跑的 MVP。
对比 Java:面试题里的“轮子” vs Django 的“全家桶”
说到这儿,不得不提 Java 生态。
最近帮朋友模拟面试,他被问到:
“如何设计一个高并发的任务系统?用 Redis 缓存?消息队列削峰?数据库读写分离?”
而我用 Django,三天就跑起来了——不是我不考虑性能,而是 MVP 阶段根本用不到那些。
Django 的哲学是:“先跑起来,再优化。”
| 能力 | Django | Java (Spring Boot) |
|---|---|---|
| 快速原型 | ⚡ 极快(自带 ORM/Admin/Auth) | ⏳ 较慢(需集成多个 starter) |
| 学习曲线 | 平缓(约定明确) | 陡峭(概念繁多) |
| 面试题深度 | 少(框架封装太好) | 多(源码/原理常考) |
| 扩展性 | 中(适合中小项目) | 高(微服务友好) |
所以,如果你在准备 Java 面试题,可能要深挖 AQS、JVM、分布式事务;但如果你用 Django 做内部工具,领导只关心:“明天能上线吗?”
踩坑记录:那些让我想砸 Mac 的瞬间
当然,过程不可能一帆风顺。
坑 1:静态文件 404
我加了个 CSS 文件,结果浏览器死活加载不到。查文档才发现,Django 默认不提供静态文件服务(生产环境交给 Nginx)。
开发环境需要加:
# settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]
并在 urls.py 加调试路由(仅 DEBUG=True 时):
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
坑 2:CSRF Token 缺失
POST 请求直接 403。原来 Django 默认开启 CSRF 保护。
解决方法要么在模板里加 {% csrf_token %},要么对 API 视图加 @csrf_exempt(不推荐)。
🙃 吐槽:前端天天喊“安全”,结果自己第一次写表单就栽在 CSRF 上。
坑 3:时区问题
created_at 显示的时间比我本地晚 8 小时。原来是 Django 默认用 UTC。
改 settings.py:
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True
搞定。
最终成果 & 心得
三天后,我按时交付了任务管理系统。虽然界面简陋(用了 Bootstrap 快速搭的),但功能完整:登录、任务增删改查、状态切换、数据归属。
最爽的是——全程没碰一行 Java,也没刷任何面试题。
这次经历让我意识到:
- 工具链成熟度决定开发效率:Django 的“电池 included”理念,让全栈新手也能快速产出。
- 前端思维可以迁移到后端:组件化(App)、状态管理(Model)、路由(URLConf),底层逻辑是通的。
- 不要被语言绑架:我会 JS,不代表我不能写 Python;会写 Vue,也不代表不能理解服务端渲染。
当然,Django 不适合高并发场景(比如秒杀、实时聊天),但对于内部工具、MVP 产品、数据后台,它依然是王者。
给前端同学的建议
如果你和我一样,想从纯前端走向全栈:
- 别怕换语言:JS 和 Python 都是动态语言,思维模式接近。
- 先跑通,再优化:不要一上来就想微服务、K8s,先把功能做出来。
- 善用框架能力:Django 的 Admin、Auth、ORM,能省下 80% 的重复劳动。
- 保持前端优势:等业务稳定后,完全可以把前端换成 Vue/React,Django 只当 API Server。
最后,别忘了——程序员最重要的不是语言,而是解决问题的能力。
哦对了,今天老张又来找我了:
“小陈,下个项目要不要试试用 Rust 写个微服务?”
我默默关掉正在看的《Rust 权威指南》,回了一句:
“行啊,不过得加钱。” 😎
(完)

评论 0