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

热更新信徒
2025-12-13 06:33
阅读 663

凌晨1点,娃终于睡了。奶瓶刚洗完,我搓了搓发酸的肩膀,打开终端——这是属于我的黄金coding时间。作为在当前这个组干了快两年的全职妈妈,白天被各种需求、会议和“妈妈妈妈”的呼唤填满,只有深夜才能静下心来敲几行代码。

最近团队在搞一个内部工具平台重构,领导突然拍板说:“试试用Django吧,Python生态好,上手快。” 我内心OS:Go不是你们之前吹上天的语言吗?结果产品小王补了一句:“前端已经用Vue写好了,后端你看着办。” 行吧,谁让我是那个“会Python又会带娃还能扛需求”的人呢?

为什么选Django而不是Go?

先别急着喷我标题党。我们组确实重度使用Go(微服务、网关、中间件清一色Go),但这次是个轻量级内部系统,要快速出原型,还要支持用户登录、权限管理、表单提交这些“祖传功能”。Go虽然性能猛如虎,但写个简单CRUD得自己搭路由、中间件、ORM,还得处理session,对一个人+娃的开发者来说,真的扛不住。

Django自带Admin、Auth、ORM、Template引擎,开箱即用。上周五晚上我试了一下,从零到能跑通登录页,只用了40分钟——要知道,这期间我还起来泡了两次奶。

“全栈工程师”在带娃程序员这里,往往意味着“前后端+哄睡+冲奶粉”全包。

环境搭建:别被pip坑了

首先确保你有Python 3.8+。我本地用的是pyenv管理版本,避免和系统Python打架:

# 创建虚拟环境(别直接污染全局!)
python -m venv django_first_site
source django_first_site/bin/activate

# 安装Django(建议指定版本,别盲目latest)
pip install Django==4.2.7

曾经有个同事直接pip install django没锁版本,第二天项目跑不起来,因为Django 5.0把某个中间件改了。运维大哥当场裂开。

生成项目骨架:

django-admin startproject mysite .
cd mysite
python manage.py startapp blog  # 假设我们要做个简易博客

这时候目录结构大概是这样:

mysite/
├── manage.py
├── mysite/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── blog/
    ├── migrations/
    ├── models.py
    ├── views.py
    └── ...

数据库设计:别一上来就搞复杂

我们内部系统最初想搞PostgreSQL+Redis缓存,后来发现——就50个用户,MySQL都算奢侈了。开发阶段直接用SQLite,省心省力。

settings.py里确认:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

定义一个简单的Post模型:

# blog/models.py
from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

然后执行迁移:

python manage.py makemigrations
python manage.py migrate

有一次忘记makemigrations直接上线,测试小姐姐跑来说“数据怎么没了”,我一看数据库空的——当场社死。从此把这两条命令写进README第一行。

前端集成:别试图在Django里写React

我知道现在流行前后端分离,但如果你只是做个内部工具,Django的模板系统+一点点HTMX或者Alpine.js,效率高到飞起。

比如展示文章列表:

<!-- blog/templates/blog/post_list.html -->
<!DOCTYPE html>
<html>
<head>
    <title>我的博客</title>
    <!-- 别忘了CSRF token! -->
    {% csrf_token %}
</head>
<body>
    <h1>文章列表</h1>
    {% for post in posts %}
        <div>
            <h2>{{ post.title }}</h2>
            <p>作者:{{ post.author.username }}</p>
            <p>{{ post.content|truncatewords:30 }}</p>
        </div>
    {% empty %}
        <p>暂无文章</p>
    {% endfor %}
</body>
</html>

视图函数:

# blog/views.py
from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.objects.all().order_by('-created_at')
    return render(request, 'blog/post_list.html', {'posts': last_10_posts})

URL配置:

# mysite/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
]

# blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.post_list, name='post_list'),
]

别笑!就这么几行,一个能看的页面就有了。产品经理看了都说“比上次快多了”。

性能与部署:别在生产环境用runserver

Django自带的runserver只适合开发。线上我们用Gunicorn + Nginx,配合systemd托管。

启动脚本示例:

# gunicorn_start.sh
#!/bin/bash
source /path/to/venv/bin/activate
cd /path/to/mysite
exec gunicorn --bind 127.0.0.1:8000 mysite.wsgi:application

Nginx反向代理:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /path/to/mysite/static/;
    }
}

静态文件别忘了收集:

python manage.py collectstatic

上次双11前上线,忘了collectstatic,CSS全崩,用户以为我们被黑客攻击了。运维小哥边骂边帮我重启,还顺手给我塞了杯奶茶——团队氛围还是暖的。

和Go微服务怎么协作?

虽然主站用Django,但我们有些计算密集型任务(比如日志分析)还是走Go写的微服务。Django通过HTTP调用它们:

import requests

def analyze_logs(post_id):
    try:
        resp = requests.post(
            'http://go-log-analyzer:8080/analyze',
            json={'post_id': post_id},
            timeout=5
        )
        return resp.json()
    except Exception as e:
        logger.error(f"Go服务挂了: {e}")
        return {"error": "暂时无法分析"}

这种混合架构其实很常见:Django做业务胶水,Go扛高性能模块。

写给同样“身兼多职”的你

说实话,学Django不是因为我多热爱它,而是它让我在有限的时间里,能把事情做完。作为一个既要debug又要换尿布的人,我需要的是“确定性”——Django的约定优于配置,让我少踩90%的坑。

如果你也在带娃、加班、赶deadline的夹缝中挣扎,不妨试试Django。它可能不够酷,不够新,但它稳、快、省心。

最后分享个小技巧:在settings.py里加一行:

if DEBUG:
    INTERNAL_IPS = ['127.0.0.1']
    # 配合django-debug-toolbar,排查SQL超方便

毕竟,少查一个Bug,就能多陪娃睡十分钟。


对比项 Django Go (原生)
开发速度 ⚡⚡⚡⚡⚡(自带轮子) ⚡⚡(需自建)
学习曲线 平缓(文档极佳) 陡峭(并发/内存管理复杂)
适合场景 中后台、MVP、内容型网站 高并发、微服务、CLI工具
带娃友好度 🌟🌟🌟🌟🌟(深夜速成) 🌟🌟(容易陷入细节出不来)

今晚就到这里吧,娃好像醒了。代码可以明天再写,但他的夜奶不能等。

下次聊聊怎么用Django Channels做实时通知——前提是我能熬过今晚的第三次夜醒。

评论 0

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