Django入门教程:搭建你的第一个Python网站
上周五晚上十点半,杭州下着小雨,我坐在工位上盯着一个祖传的Java后台系统发呆。产品经理刚刚在群里@我说:“这个需求很简单,下周三上线。”——又是熟悉的配方,熟悉的味道。
作为一个在阿里和网易之间反复横跳过几回的老油条,我其实早就习惯了这种节奏。但这次不一样:后端要快、前端要炫、还要能扛住双11级别的流量(虽然只是个内部工具)。我当时就想:得找个趁手的框架,快速搭个原型出来,Django 突然就闪进了脑海。
说来惭愧,虽然这些年用过 Flask、FastAPI,甚至试过用 Node.js 搞后端(别问,问就是被前端同事带偏了),但真正让我觉得“写代码像呼吸一样自然”的,还是 Django。尤其是自从我开始用 Cursor 写代码以后——它对 Django 的理解简直比我自己还清楚,经常我刚敲了个 def,它就把整个 view 函数骨架+注释+单元测试都补全了。深夜 coding 效率直接拉满。
所以今天这篇,不搞那些花里胡哨的理论,就手把手带你用 Django 搭个最简单的 Python 网站。新手友好,包教包会,学会了就能去跟产品经理说:“功能做完了,你验收吧。”
为什么选 Django?不是有 Flask 吗?
先别急着喷。我知道很多人一提 Python Web 就说 Flask 轻量、灵活。但兄弟,轻量不等于省事。Flask 像是一辆自行车,你想加个导航、装个音响、再配个防盗锁?行,自己焊。而 Django 是一辆出厂就带空调、倒车影像、自动泊车的电车——你只需要踩油门。
特别是当你关注架构设计和代码质量的时候,Django 的 ORM、Admin、Auth、Migrations 这些开箱即用的功能,能让你少踩 80% 的坑。我在阿里那会儿,团队强制要求所有内部工具必须用 Django,理由就一条:“别重复造轮子,把时间花在业务逻辑上。”
第一步:环境搭建(别被 pip 折磨)
先装 Python(3.8+),然后:
pip install django
如果卡在下载速度上——别慌,咱杭州程序员都懂,换源是基本操作:
pip install django -i https://pypi.tuna.tsinghua.edu.cn/simple/
接着创建项目:
django-admin startproject mysite
cd mysite
python manage.py runserver
浏览器打开 http://127.0.0.1:8000,看到那个火箭图标没?恭喜你,已经击败了全国 50% 的初学者(剩下 50% 还在配环境)。
🚨 注意:生产环境千万别用
runserver!那是开发服务器,性能堪比树懒。后面我会说怎么用 Gunicorn + Nginx 部署。
第二步:搞个“留言板”练练手
光看欢迎页太无聊,咱们来个经典场景:用户提交留言,后端存到数据库,页面实时显示。
1. 创建 App
Django 项目由多个 App 组成。比如用户系统、订单系统、评论系统,各是一个 App。
python manage.py startapp guestbook
然后在 mysite/settings.py 的 INSTALLED_APPS 里加上:
INSTALLED_APPS = [
...
'guestbook',
]
2. 设计模型(Model)
在 guestbook/models.py 里定义数据结构:
from django.db import models
class Message(models.Model):
content = models.TextField()
author = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.author}: {self.content[:20]}..."
这玩意儿就是 ORM 的魅力——你不用写一行 SQL,Django 自动帮你生成表结构。
然后执行迁移:
python manage.py makemigrations
python manage.py migrate
搞定!数据库(默认是 SQLite,适合开发)里已经有 guestbook_message 表了。
3. 写视图(View)
在 guestbook/views.py:
from django.shortcuts import render, redirect
from .models import Message
def index(request):
if request.method == "POST":
content = request.POST.get("content")
author = request.POST.get("author")
if content and author:
Message.objects.create(content=content, author=author)
return redirect("index") # 提交后刷新页面
messages = Message.objects.all().order_by("-created_at")
return render(request, "guestbook/index.html", {"messages": messages})
这里注意:我们用了 redirect 避免重复提交(POST 后重定向 GET,经典的 PRG 模式)。不然用户狂点 F5,数据库就炸了——别问我怎么知道的,去年双11前夜就因为这个 Bug 被运维拉去喝茶。
4. 配置路由(URL)
在 guestbook/urls.py(如果没有就新建):
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
然后在 mysite/urls.py 中 include:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('guestbook.urls')),
]
5. 写前端模板(HTML + JavaScript)
Django 自带模板引擎。在 guestbook/templates/guestbook/index.html:
<!DOCTYPE html>
<html>
<head>
<title>我的留言板</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 2rem auto; }
.message { padding: 0.5rem; border-bottom: 1px solid #eee; }
</style>
</head>
<body>
<h1>留言板</h1>
<form method="post">
{% csrf_token %}
<input name="author" placeholder="你的名字" required>
<textarea name="content" placeholder="说点什么..." required></textarea>
<button type="submit">提交</button>
</form>
<div id="messages">
{% for msg in messages %}
<div class="message">
<strong>{{ msg.author }}</strong>: {{ msg.content }}
<small>{{ msg.created_at|date:"Y-m-d H:i" }}</small>
</div>
{% endfor %}
</div>
<!-- 来点 JavaScript 让体验更丝滑 -->
<script>
// 简单防抖:避免用户狂点提交
document.querySelector('form').addEventListener('submit', function(e) {
const btn = this.querySelector('button');
btn.disabled = true;
btn.textContent = '提交中...';
setTimeout(() => {
btn.disabled = false;
btn.textContent = '提交';
}, 1000);
});
</script>
</body>
</html>
注意 {% csrf_token %} ——这是 Django 的安全机制,防止跨站请求伪造。如果你漏了它,表单提交会直接 403,然后你就会在凌晨三点对着屏幕骂娘。
关于 JavaScript 的一点真心话
很多 Python 后端觉得 JS 是“玩具语言”,但现实是:用户体验靠前端,而前端离不开 JS。哪怕你只用 Django 模板渲染静态页,加点 JS 也能让交互提升一个档次。
上面那段防抖代码,虽然简单,但在真实项目中能减少大量无效请求。我在网易时,有个同事连“加载中”都不加,结果测试妹子疯狂点按钮,把接口打挂了……后来他被请去吃了一顿“茶”。
生产部署?别慌,记住这几点
开发完只是开始。上线才是噩梦的起点。分享几个血泪经验:
| 事项 | 开发环境 | 生产环境 |
|---|---|---|
| 数据库 | SQLite | PostgreSQL / MySQL |
| 静态文件 | Django 自带服务 | Nginx 托管 |
| 服务器 | runserver | Gunicorn + Supervisor |
| DEBUG | True | 必须 False |
| SECRET_KEY | 随便写 | 从环境变量读取 |
特别强调:DEBUG=False 时,静态文件不会自动提供! 很多人第一次部署完发现 CSS 全没了,一脸懵。解决方法:
- 设置
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') - 执行
python manage.py collectstatic - 配置 Nginx 指向这个目录
另外,数据库别用 SQLite 上生产!它不支持并发写入,流量一高就锁表。我们团队曾经有个内部工具用 SQLite,结果 HR 部门集体打卡时,系统直接瘫痪——那天下午整个办公室都在喊:“谁又改数据库了?!”
最后:为什么我坚持用 Django?
回到开头。上周五的需求,我用 Django + Cursor,三个小时搞定 MVP。第二天演示时,产品经理眼睛都亮了:“这界面怎么这么快就出来了?”
其实不是我多牛,是 Django 帮我省去了无数琐碎决策:用什么 ORM?怎么处理表单?用户登录怎么做?这些它都给你想好了。而 Cursor 则帮我自动生成样板代码、写测试、甚至优化查询——比如它提醒我把 Message.objects.all() 改成 select_related,虽然这个例子用不上,但在复杂模型里能省 50% 查询。
作为一个喜欢深夜写代码、追求代码质量的人,Django 的“约定优于配置”哲学,加上现代 AI 工具的加持,真的让我找回了写代码的乐趣。
所以,如果你也想快速做出一个靠谱的 Python 网站,别犹豫了。django-admin startproject,走起!
P.S. 如果你卡在某个步骤,欢迎留言。不过别问“为什么我页面 404”——99% 是 URL 配错了,剩下 1% 是你忘了重启 runserver 😅

评论 0