一、为什么还学 Django?——2025 年的新理由

  1. 5.2 LTS 支持到 2027,官方承诺至少 3 年安全补丁。

  2. Python 3.12 适配:match-case、泛型、性能提升 15%。

  3. 异步生态成熟:ASGI + Django-Channels 4.x,WebSocket 开箱即用。

  4. Admin 2.0 视觉大改,低代码后台真香。

  5. 内置 Postgres 向量扩展,直接玩 AI 语义搜索。

二、5 分钟跑通第一个 Demo(含热重载)

# 1. 建项目+虚拟环境(Python 3.12 推荐)
python3.12 -m venv .venv && source .venv/bin/activate
pip install -U pip django==5.2.5

# 2. 一键初始化
django-admin startproject demo && cd demo
python manage.py startapp blog
# 让 Demo 可远程访问(局域网调试)
echo 'ALLOWED_HOSTS=["*"]' >> demo/settings.py
python manage.py runserver 0:8000

三、MTV 真比 MVC 香?一张图看懂

传统 MVC             Django MTV
Model —— 数据        Model —— 数据
View  —— 表现        Template —— 表现
Controller —— 调度   View —— 调度 + 业务

结论:Django 把「如何展示」彻底剥离到 Template,View 只关心“拿数据+选模板”,职责更单一,单元测试更好写。

四、ORM 速通:从建表到关联只需 6 行代码

# blog/models.py
from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=20, unique=True)

class Post(models.Model):
    title = models.CharField(max_length=120)
    body = models.TextField()
    tags = models.ManyToManyField(Tag, related_name='posts')
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created']
python manage.py makemigrations
python manage.py migrate

Django 会自动

  • 建表 blog_postblog_tagblog_post_tags

  • 加索引、外键约束

  • 生成 Admin 后台(下一节)

五、Admin 2.0 可视化——不写一行前端

# blog/admin.py
from django.contrib import admin
from .models import Post, Tag

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'created')
    list_filter = ('tags', 'created')
    search_fields = ('title', 'body')

访问 http://127.0.0.1:8000/admin → 完成增删改查+模糊搜索+过滤导出 CSV 也只需 list_export = ['csv']

六、URL 与视图:PATH 转换器 + 命名空间实战、

# demo/urls.py(根路由)
from django.urls import path, include

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

# blog/urls.py
from django.urls import path
from .views import post_list, post_detail

app_name = 'blog'
urlpatterns = [
    path('', post_list, name='index'),
    path('<int:year>/<slug:slug>/', post_detail, name='detail'),
]

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

def post_detail(request, year, slug):
    post = get_object_or_404(Post, created__year=year, slug=slug)
    return render(request, 'blog/detail.html', {'post': post})

亮点

  • <int:year> 自动强制类型 + 404 边界判断

  • namespace + app_name 解决多 App 同名路由冲突

  • 模板中反向解析:

<a href="{% url 'blog:detail' year=2025 slug=django-note %}">阅读更多</a>

七、模板:继承 + 静态文件一次讲透

templates/
├─ base.html        # 母版
└─ blog/
   ├─ list.html     # 列表页
   └─ detail.html   # 详情页
<!-- base.html -->
{% load static %}
<!doctype html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>{% block title %}Django5 笔记{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/bulma.min.css' %}">
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>

<!-- detail.html -->
{% extends 'base.html' %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<section class="section">
  <h1 class="title">{{ post.title }}</h1>
  <div class="content">{{ post.body|linebreaks }}</div>
</section>
{% endblock %}

静态文件收集(生产必做)

mkdir static css
# 开发阶段
DEBUG=True  # Django 自动 serve
# 上线阶段
DEBUG=False
python manage.py collectstatic  # 一键收集到 STATIC_ROOT

八、进阶:自定义中间件 + 异步视图

1. 中间件(记录 IP + 响应头)

# blog/middleware.py
class IPTimeMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        print('IP:', request.META.get('REMOTE_ADDR'))
        response = self.get_response(request)
        response['X-Powered-By'] = 'Django 5.2'
        return response

注册:settings.MIDDLEWARE += ['blog.middleware.IPTimeMiddleware']

2. 异步视图(Django 5.x 原生支持)

# blog/views.py
import asyncio
from django.http import JsonResponse

async def api_slow(request):
    await asyncio.sleep(3)          # 非阻塞 IO
    return JsonResponse({'msg': 'ok'})

压测对比:同步 3s×100 并发 = 300s 总时长;异步 ≈ 3s 总时长,CPU 利用率翻倍


九、生产配置清单( checklist 直接抄)

配置项 开发 生产
DEBUG True False
ALLOWED_HOSTS ["*"] ["www.yourdomain.com"]
数据库 SQLite PostgreSQL 15 (pgbouncer 连接池)
静态文件 Django 自动 Nginx alias /static/
媒体文件 Django 自动 对象存储 OSS/S3
缓存 内存 Redis 7 + Django-Redis
日志 console RotatingFileHandler + Sentry
HTTPS 关闭 强制 HSTS + Let’s Encrypt
安全 默认 SECURE_SSL_REDIRECT=True SECURE_HSTS_SECONDS=31536000

十、一键部署脚本(Ubuntu 22.04 + gunicorn + nginx)

# 安装依赖
sudo apt update && sudo apt install -y python3-pip python3-venv nginx git
# 拉代码
git clone https://github.com/YourName/django5-note.git /srv/django5
cd /srv/django5
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# 收集静态
python manage.py collectstatic --noinput
# gunicorn 系统服务
sudo tee /etc/systemd/system/gunicorn.service <<EOF
[Unit]
Description=django5
After=network.target

[Service]
User=www-data
WorkingDirectory=/srv/django5
ExecStart=/srv/django5/venv/bin/gunicorn demo.wsgi:application -b 127.0.0.1:8000
Restart=always

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now gunicorn

# Nginx 反向代理
sudo tee /etc/nginx/sites-available/django5 <<EOF
server {
    listen 80;
    server_name yourdomain.com;
    location /static/ { alias /srv/django5/staticfiles/; }
    location / { proxy_pass http://127.0.0.1:8000; }
}
EOF
sudo ln -s /etc/nginx/sites-available/django5 /etc/nginx/sites-enabled
sudo nginx -t && sudo systemctl reload nginx

Let’s Encrypt 免费 HTTPS

sudo snap install --classic certbot
sudo certbot --nginx -d yourdomain.com

十一、常见踩坑 & 排查技巧

  1. 「CSRF 验证失败」 → 确认模板里 {% csrf_token %} + 中间件未禁用。

  2. 「collectstatic 样式 404」 → Nginx 用户无权限 chown -R www-data:www-data staticfiles

  3. 「异步视图阻塞」 → 检查 asgi.py 是否使用 get_asgi_application() + uvicorn 启动。

  4. 「MySQL 8 认证插件」pip install mysqlclient==2.2.*ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'pwd';

  5. 「时区差 8 小时」 → 设置 TIME_ZONE = 'Asia/Shanghai' 并且 USE_TZ = True

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐