Django入门教程:搭建你的第一个Python网站

CD还没发
2025-12-14 17:48
阅读 593

上周五晚上十点半,杭州下着小雨,我坐在工位上盯着一个祖传的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.pyINSTALLED_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 全没了,一脸懵。解决方法:

  1. 设置 STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
  2. 执行 python manage.py collectstatic
  3. 配置 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

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝