我在成都用Django搭的第一个网站:从前端狗到全栈萌新的奇妙旅程
上周五晚上十点半,我盯着屏幕上闪烁的光标发呆。
产品经理又提了个“小需求”:临时要做一个内部数据展示页面,下周三上线。
我翻了翻技术栈——React?太重。Vue?没后端配合。Flask?单文件写起来爽,但团队里没人会维护。
突然想起前两天刷知乎看到的一句话:“你前端再牛,也得有个后端给你喂接口。”
于是,我默默打开了终端,敲下:
pip install django
是的,作为一个常年泡在 CSS 动画和 useEffect 陷阱里的前端仔,我终于要亲手写 Python 后端了。
为什么是 Django?而不是 Java Spring Boot?
别误会,我不是黑 Java。我们公司老系统就是 Spring Boot + MyBatis,稳如老狗。但问题是——资源有限。
我们团队就仨人:一个产品经理(兼 UI 设计),一个测试(兼职运维),还有一个我(前端 + 临时后端 + 紧急客服)。
让测试去配 Tomcat?让产品去改 application.yml?算了吧。
Java 虽然强大,但启动一个最简单的 Web 服务也得:
- 配 Maven
- 写 Controller、Service、DAO
- 配置 DataSource
- 打包成 jar
- 写 Dockerfile(如果运维心情好)
而 Django 呢?官方文档第一行就写着:
“Django is a high-level Python web framework that encourages rapid development.”
翻译成人话:快,糙,猛。
而且,Python 的语法对前端来说简直亲妈——缩进代替花括号,列表推导式像 JS 的 map,字典就是对象……我甚至不用查文档就能猜出 request.POST.get('name') 是干啥的。
最关键的是:Django 自带 admin 后台、ORM、用户系统、路由、模板引擎。
这意味着我不用从零造轮子,也不用求着后端大哥帮我写个登录接口。
搭建过程:从 startproject 到跑起来
第一步:创建项目(真的只要一行命令)
django-admin startproject mysite
cd mysite
python manage.py runserver
浏览器打开 http://127.0.0.1:8000,熟悉的火箭图标出现——成了!
💡 小贴士:如果你在国内,建议先换 pip 源,不然
pip install django可能卡到你想砸键盘。清华源yyds。
第二步:创建 App —— 别被名字吓到
Django 里“App”不是指手机应用,而是功能模块。比如用户系统是一个 app,博客是一个 app。
python manage.py startapp polls # 官方教程喜欢叫 polls,我也懒得改
然后去 settings.py 里注册:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
# ... 其他默认的
'polls', # ← 加这一行
]
第三步:定义模型(Model)——数据库长这样
我想做个简单的“留言墙”,用户能提交姓名和内容。
在 polls/models.py 里写:
from django.db import models
class Message(models.Model):
name = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.name}: {self.content[:20]}..."
这比手写 SQL 或者 JPA 注解舒服多了。CharField 对应 VARCHAR,TextField 是 TEXT,auto_now_add 自动填创建时间——不用写 getter/setter,不用配 XML 映射。
然后生成迁移文件并执行:
python manage.py makemigrations
python manage.py migrate
数据库(默认 SQLite)自动建表!连表名都是 polls_message,规范得一批。
写视图和模板:前端人的舒适区
Django 支持两种视图写法:函数式(FBV)和类视图(CBV)。
作为前端,我本能地选了 FBV——更像 Express 或 Koa 的路由处理。
在 polls/views.py:
from django.shortcuts import render, redirect
from .models import Message
def index(request):
if request.method == "POST":
name = request.POST.get("name")
content = request.POST.get("content")
if name and content:
Message.objects.create(name=name, content=content)
return redirect("/") # 提交后刷新页面
messages = Message.objects.all().order_by("-created_at")
return render(request, "index.html", {"messages": messages})
是不是有点像 Node.js 的 req.body?只不过这里用 .POST.get() 而不是 req.body.name。
模板放在 polls/templates/index.html(Django 会自动找 templates 目录):
<!DOCTYPE html>
<html>
<head>
<title>留言墙</title>
<style>
body { font-family: -apple-system, sans-serif; padding: 2rem; }
.message { margin-bottom: 1rem; padding: 0.5rem; background: #f5f5f5; border-radius: 4px; }
</style>
</head>
<body>
<h1>欢迎留言!</h1>
<form method="post">
{% csrf_token %} <!-- Django 的防 CSRF 必加 -->
<input type="text" name="name" placeholder="你的名字" required>
<textarea name="content" placeholder="说点什么..." required></textarea>
<button type="submit">提交</button>
</form>
<h2>最新留言</h2>
{% for msg in messages %}
<div class="message">
<strong>{{ msg.name }}</strong> · {{ msg.created_at|date:"Y-m-d H:i" }}
<p>{{ msg.content }}</p>
</div>
{% empty %}
<p>还没有留言,快来抢沙发!</p>
{% endfor %}
</body>
</html>
注意 {% csrf_token %} ——这是 Django 的安全机制,不加的话 POST 请求会被拒。第一次踩坑时我还以为是跨域问题,debug 半小时才发现漏了这行。
路由配置:URL 怎么映射到视图?
Django 用 urls.py 管理路由。主项目的 mysite/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('polls.urls')), # 把根路径交给 polls 处理
]
然后在 polls/urls.py(需要自己新建):
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
这种“主路由 + 子路由”的设计,特别适合大型项目拆分。比 Flask 那种全局 @app.route 清晰多了。
启用 Admin 后台:白嫖管理界面
Django 最香的功能之一:自动生成后台。
先创建超级用户:
python manage.py createsuperuser
# 按提示输入用户名、邮箱、密码
然后在 polls/admin.py 注册模型:
from django.contrib import admin
from .models import Message
admin.site.register(Message)
重启服务,访问 /admin,用刚才的账号登录——Boom!一个完整的 CRUD 后台出来了,支持搜索、过滤、排序,连时间格式都本地化好了。
🤯 当时我真的惊了:这玩意儿在 Java 里至少得用 Thymeleaf + Spring Security + 自己写一堆 HTML 才能搞出来,而且样式还丑。
生产环境部署:别再用 runserver 了!
开发时 runserver 很方便,但生产环境绝对不能这么干。
上周我们测试环境就因为直接用 runserver 跑,结果并发一高直接 502,运维差点把我挂墙上。
正确姿势:Gunicorn + Nginx
pip install gunicorn
gunicorn mysite.wsgi:application --bind 0.0.0.0:8000
然后用 Nginx 反向代理静态文件,并做负载均衡(虽然现在只有一个进程)。
另外,记得改 settings.py:
DEBUG = False # 必须关!否则会泄露敏感信息
ALLOWED_HOSTS = ['your-domain.com', 'localhost'] # 不加这个会 400 错误
数据库也别用 SQLite 了,换成 PostgreSQL 或 MySQL:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'myuser',
'PASSWORD': 'mypass',
'HOST': 'localhost',
'PORT': '5432',
}
}
和 Java 项目的对比:资源消耗 vs 开发效率
为了公平起见,我拉了组内一位 Java 老哥一起做了个对比实验:
| 项目 | Django (Python) | Spring Boot (Java) |
|---|---|---|
| 代码行数 | ~80 行 | ~220 行 |
| 依赖数量 | 1 个 (Django) | 5+ (Spring Web, JPA, Validation, etc.) |
| 启动时间 | 0.8 秒 | 3.5 秒 |
| 内存占用 | ~60 MB | ~300 MB |
| 首次请求响应 | 50ms | 120ms |
| 开发体验 | 快速迭代,热重载 | 需要 rebuild,慢 |
数据来源:我的 MacBook Air M1,仅供参考
结论很明显:对于小型内部工具、MVP 产品、快速原型,Django 的开发效率碾压 Java。
但如果是高并发、强事务、复杂业务逻辑的系统(比如支付、金融),Java 的生态和稳定性还是更靠谱。
所以,别说什么“Python 不行”,关键看场景。用错工具才是最大的浪费资源。
最后:前端仔学 Django,值不值?
值!太值了!
自从会了 Django,我不再是“只会调接口的前端”。
现在我能独立交付一个完整的小型 Web 应用:从数据库设计、API 编写、页面渲染,到部署上线。
上周那个“小需求”,我周二下午搞定,周三演示时产品经理眼睛都亮了:“这速度,比后端还快?”
其实哪有什么魔法,不过是站在巨人的肩膀上——Django 这个巨人,已经帮我扛起了 80% 的基建工作。
如果你也在成都,过着“火锅配代码”的悠闲日子,不妨试试 Django。
不用成为 Python 大神,只要会写函数、懂点 ORM,就能做出能跑的网站。
毕竟,在这个卷成麻花的行业里,多一项技能,就少一次求人。
P.S. 刚才写完这篇文章,产品又来找我:“那个留言墙能不能加个点赞功能?”
我笑了笑,回了一句:“加钱,或者等我喝完这杯瑞幸。”
然后默默打开了models.py……

评论 0