Django 框架科普:从请求到数据库的一次完整旅程

Django 是一个基于 Python 的全栈 Web 框架,适合构建后台管理系统、业务 API、内容平台、电商系统和企业内部工具。

它的核心价值是:开发者不必从零拼装路由、数据库访问、用户认证、后台管理、表单校验等基础能力,而是可以把精力集中在业务规则上。


1. Django 解决什么问题?

一个 Web 服务通常要处理:

  • 用户访问网址后,如何定位处理代码?
  • 如何读取请求中的参数、请求头、文件和用户身份?
  • 如何查询和修改数据库?
  • 如何校验用户输入?
  • 如何生成 HTML 页面或 JSON 数据?
  • 如何限制接口权限?
  • 如何记录日志、处理异常、管理配置?
  • 如何做数据库迁移和后台管理?

Django 提供了一套相互协作的标准组件来解决这些问题。

客户端
  ↓ HTTP Request
Django 路由系统
  ↓
View(视图 / 业务入口)
  ↓
Model / ORM(数据库操作)
  ↓
Serializer 或 Template(输出数据)
  ↓ HTTP Response
客户端

2. Django 的核心设计:MVT

Django 常被称为 MVT 架构:

层级 全称 职责
Model 数据模型 描述和操作数据库
View 视图 接收请求、处理业务、返回响应
Template 模板 生成 HTML 页面

它和常见的 MVC 很像:

MVC             Django MVT
Controller  →   View
View        →   Template
Model       →   Model

对于前后端分离项目,Template 常被弱化,View 通常直接返回 JSON。


3. 一个请求在 Django 中如何流转?

假设客户端请求:

GET /api/users/42/

处理过程通常是:

1. Web Server 接收请求
2. Django 加载配置与中间件
3. URL 路由匹配 /api/users/42/
4. View 接收到 request 和 user_id=42
5. View 使用 ORM 查询数据库
6. 将对象转换为 JSON 或 HTML
7. 中间件处理响应
8. 返回 HTTP 响应给客户端

伪代码如下:

# urls.py
path("api/users/<int:user_id>/", views.user_detail)
# views.py
def user_detail(request, user_id):
    user = User.objects.get(id=user_id)
    return JsonResponse({
        "id": user.id,
        "name": user.name,
    })

4. 项目配置:Settings

Django 项目有一个配置中心,通常叫 settings.py。它负责声明整个应用如何运行。

常见配置包括:

DEBUG = False

INSTALLED_APPS = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
]

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": "db.sqlite3",
    }
}

常见配置项:

配置 作用
DEBUG 是否开启开发调试模式
INSTALLED_APPS 已安装的 Django App
MIDDLEWARE 请求/响应处理链
DATABASES 数据库连接配置
CACHES 缓存配置
LOGGING 日志配置
ALLOWED_HOSTS 允许访问的主机名
ROOT_URLCONF 根路由模块
TEMPLATES 模板引擎配置
STATIC_URL 静态文件访问前缀

读取配置:

from django.conf import settings

if settings.DEBUG:
    print("当前为开发调试模式")

DEBUG 的意义

DEBUG = True

通常用于开发环境,特点:

  • 页面会显示详细报错堆栈;
  • 静态文件处理更方便;
  • 有利于排查问题;
  • 不适合生产环境。
DEBUG = False

通常用于生产环境,特点:

  • 避免向外暴露代码路径、配置和报错详情;
  • 需要正确配置 ALLOWED_HOSTS
  • 应通过日志系统排查异常。

生产环境不要开启 DEBUG=True


5. URL 路由:django.urls

URL 路由决定“什么路径交给什么代码处理”。

from django.urls import path
from . import views

urlpatterns = [
    path("hello/", views.hello),
    path("users/<int:user_id>/", views.user_detail),
]

请求和路由的关系:

GET /hello/
        ↓
views.hello

GET /users/100/
        ↓
views.user_detail(request, user_id=100)

路由参数

path("articles/<int:article_id>/", views.article_detail)

对应视图:

def article_detail(request, article_id):
    return JsonResponse({"article_id": article_id})

Django 常用路径转换器:

写法 匹配内容
<int:id> 整数
<str:name> 普通字符串
<slug:slug> URL 友好字符串
<uuid:id> UUID
<path:value> / 的路径

路由拆分

大型项目通常按业务模块拆分路由。

# project/urls.py
from django.urls import include, path

urlpatterns = [
    path("api/users/", include("users.urls")),
    path("api/orders/", include("orders.urls")),
]
# users/urls.py
urlpatterns = [
    path("", views.user_list),
    path("<int:user_id>/", views.user_detail),
]

6. View:请求处理入口

View 的职责是:

  1. 接收请求;
  2. 读取参数;
  3. 调用业务逻辑;
  4. 查询或更新数据;
  5. 返回 HTTP 响应。

函数视图

最简单的形式:

from django.http import JsonResponse

def health_check(request):
    return JsonResponse({
        "status": "ok",
    })

读取查询参数:

def user_list(request):
    page = request.GET.get("page", 1)
    return JsonResponse({"page": page})

对于:

GET /users/?page=2

page 的值是 "2",需要时自行转换为整数。

类视图

当一个资源需要处理多种 HTTP 方法时,类视图更清晰。

from django.http import JsonResponse
from django.views import View

class UserView(View):
    def get(self, request):
        return JsonResponse({"method": "GET"})

    def post(self, request):
        return JsonResponse({"method": "POST"})

路由:

path("users/", UserView.as_view())

请求映射:

GET  /users/  → UserView.get()
POST /users/  → UserView.post()

7. HTTP 请求与响应

Django 用 HttpRequest 表示请求,用 HttpResponse 表示响应。

请求对象

def example(request):
    method = request.method
    query_params = request.GET
    form_data = request.POST
    headers = request.headers
    raw_body = request.body
    files = request.FILES
    current_user = request.user

常见场景:

def search(request):
    keyword = request.GET.get("keyword", "")
    return JsonResponse({"keyword": keyword})

请求:

GET /search/?keyword=django

响应对象

from django.http import HttpResponse, JsonResponse

def text_response(request):
    return HttpResponse("Hello")

def json_response(request):
    return JsonResponse({
        "code": 0,
        "message": "success",
        "data": {},
    })

指定状态码:

return JsonResponse(
    {"message": "not found"},
    status=404,
)

常见状态码:

状态码 含义
200 请求成功
201 创建成功
204 成功但无返回内容
400 请求参数错误
401 未认证
403 无权限
404 资源不存在
500 服务端异常

8. Model 与 ORM:用 Python 操作数据库

Django ORM 是其最重要的能力之一。它让开发者可以用 Python 类描述数据库表,并用 Python 方法完成增删改查。

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    age = models.IntegerField(default=0)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

这个类大致对应一张用户表:

user
├── id
├── name
├── email
├── age
├── is_active
└── created_at

常见字段

字段 用途
CharField 短文本
TextField 长文本
IntegerField 整数
BooleanField 布尔值
DateField 日期
DateTimeField 日期时间
DecimalField 精确小数,如金额
JSONField JSON 数据
EmailField 邮箱
URLField URL
FileField 文件
ImageField 图片

创建数据

User.objects.create(
    name="Alice",
    email="alice@example.com",
    age=18,
)

查询数据

User.objects.all()

User.objects.get(id=1)

User.objects.filter(is_active=True)

User.objects.filter(age__gte=18)

User.objects.order_by("-created_at")

User.objects.first()

User.objects.count()

User.objects.exists()

get() 找不到或结果超过一条会抛异常;filter() 始终返回 QuerySet,即使没有结果也不会抛异常。

更新数据

user = User.objects.get(id=1)
user.age = 20
user.save()

批量更新:

User.objects.filter(is_active=False).update(is_active=True)

删除数据

User.objects.filter(id=1).delete()

9. 表关系

实际业务中,表之间往往有关联。

一对多:ForeignKey

一个用户可以拥有多个订单。

class Order(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="orders",
    )
    amount = models.DecimalField(max_digits=10, decimal_places=2)

查询:

order.user
user.orders.all()

一对一:OneToOneField

一个用户对应一份扩展资料。

class UserProfile(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
    )
    avatar = models.URLField()

多对多:ManyToManyField

一个用户可拥有多个角色,一个角色也可分配给多个用户。

class Role(models.Model):
    name = models.CharField(max_length=50)

class User(models.Model):
    roles = models.ManyToManyField(Role)

10. 查询优化:避免 N+1 问题

下面的代码可能触发 N+1 次数据库查询:

orders = Order.objects.all()

for order in orders:
    print(order.user.name)

原因是每访问一次 order.user,都可能额外查询一次用户表。

对于外键或一对一关系,使用 select_related()

orders = Order.objects.select_related("user")

对于多对多或反向关系,使用 prefetch_related()

users = User.objects.prefetch_related("roles")

这是 Django 项目性能优化中非常重要的一点。


11. 数据库迁移:让模型变成表

修改 Model 后,需要通过迁移把变更同步到数据库。

python manage.py makemigrations
python manage.py migrate

流程:

修改 models.py
      ↓
makemigrations:生成迁移文件
      ↓
migrate:执行迁移,修改数据库结构

迁移文件应纳入版本控制,因为它是数据库结构演进记录。


12. 表单与数据校验

Django 的 Form 可用于校验用户输入。

from django import forms

class UserForm(forms.Form):
    name = forms.CharField(max_length=100)
    age = forms.IntegerField(min_value=0)

使用:

def create_user(request):
    form = UserForm(request.POST)

    if not form.is_valid():
        return JsonResponse({"errors": form.errors}, status=400)

    name = form.cleaned_data["name"]
    age = form.cleaned_data["age"]
    return JsonResponse({"name": name, "age": age})

ModelForm 可以基于 Model 自动创建表单:

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ["name", "email", "age"]

在纯 API 项目中,通常会使用 Django REST Framework 的 Serializer 替代 Form。


13. 认证、登录与权限

Django 内置用户认证系统 django.contrib.auth

认证

from django.contrib.auth import authenticate

user = authenticate(
    request,
    username="alice",
    password="password",
)

认证成功时返回用户对象,失败时返回 None

登录与退出

from django.contrib.auth import login, logout

login(request, user)
logout(request)

保护视图

from django.contrib.auth.decorators import login_required

@login_required
def profile(request):
    return JsonResponse({
        "username": request.user.username,
    })

自定义用户模型

新项目通常建议一开始就自定义用户模型,避免后续扩展困难。

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    employee_id = models.CharField(max_length=64, unique=True)

引用当前用户模型时,推荐:

from django.contrib.auth import get_user_model

User = get_user_model()

而不要硬编码某个内置 User 类。


14. Middleware:请求与响应的处理链

中间件是全局拦截器。请求进入 View 前和响应离开 Django 前,都可以被中间件处理。

常见用途:

  • 请求日志;
  • Trace ID;
  • 用户认证;
  • Session;
  • 安全响应头;
  • 跨域处理;
  • 异常统一处理;
  • 限流。

示例:

import logging

logger = logging.getLogger(__name__)

class RequestLogMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        logger.info("request: %s %s", request.method, request.path)

        response = self.get_response(request)

        logger.info("response: %s", response.status_code)
        return response

注册:

MIDDLEWARE = [
    "myapp.middleware.RequestLogMiddleware",
]

中间件顺序很重要:请求按从上到下执行,响应按从下到上返回。

请求:   Middleware A → Middleware B → View
响应:   Middleware A ← Middleware B ← View

15. Django Admin:自动后台管理

Django 自带后台管理系统,可以快速管理数据库记录。

注册模型:

from django.contrib import admin
from .models import User

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "email", "is_active")
    search_fields = ("name", "email")
    list_filter = ("is_active",)

创建管理员:

python manage.py createsuperuser

然后访问:

/admin/

Admin 特别适合内部运营后台、数据维护和开发调试,但复杂业务后台通常需要自行开发业务页面或 API。


16. 缓存:减少重复计算和数据库压力

Django 提供统一的缓存接口,可接入本地缓存、Redis、Memcached 等。

from django.core.cache import cache

cache.set("user:1", {"name": "Alice"}, timeout=300)

user = cache.get("user:1")

cache.delete("user:1")

常见缓存策略:

场景 缓存内容
热点详情页 对象或 JSON 结果
高频配置 配置数据
复杂统计 聚合计算结果
第三方接口 调用返回结果
验证码 短时有效数据
限流 请求计数

注意:缓存是性能优化手段,不应成为唯一可信的数据来源。


17. 事务:保证数据一致性

多个数据库操作必须“要么全成功、要么全失败”时,使用事务。

from django.db import transaction

@transaction.atomic
def create_order(user, items):
    order = Order.objects.create(user=user)

    for item in items:
        OrderItem.objects.create(
            order=order,
            product_id=item["product_id"],
            quantity=item["quantity"],
        )

    return order

如果中途出现异常,事务会回滚,避免出现“订单已创建但订单项不完整”的脏数据。

也可以使用上下文形式:

with transaction.atomic():
    # 多个数据库写操作
    pass

18. Signals:事件通知机制

Signal 是一种事件钩子机制,可以在特定事件发生后执行额外逻辑。

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def after_user_created(sender, instance, created, **kwargs):
    if created:
        print("新用户已创建", instance.id)

常用信号:

信号 触发时机
pre_save 保存前
post_save 保存后
pre_delete 删除前
post_delete 删除后
m2m_changed 多对多关系变化时

Signal 很方便,但不要把关键核心业务过度隐藏在 Signal 中,否则调用链会难以理解和调试。


19. 日志与异常处理

生产服务应该用日志记录问题,而不是依赖 print()

import logging

logger = logging.getLogger(__name__)

def create_user(request):
    try:
        user = User.objects.create(name="Alice")
        logger.info("user created: id=%s", user.id)
        return JsonResponse({"id": user.id})
    except Exception:
        logger.exception("failed to create user")
        return JsonResponse({"message": "internal error"}, status=500)

logger.exception() 会自动记录异常堆栈,适合 except 代码块。

基本日志配置示意:

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "INFO",
    },
}

日志中不应记录密码、令牌、身份证号、完整手机号、Cookie、授权请求头等敏感信息。


20. Django REST Framework:构建 API 的常用扩展

Django 本身可以返回 JSON,但如果要构建规范 REST API,通常使用 Django REST Framework(DRF)。

核心能力:

  • Serializer:对象与 JSON 的转换、请求参数校验;
  • APIView:面向 API 的基础 View;
  • GenericAPIView:通用 API 基类;
  • ViewSet:按资源组织 CRUD 接口;
  • Router:自动生成 URL;
  • Authentication:身份认证;
  • Permission:权限控制;
  • Pagination:分页;
  • Filter:过滤、搜索、排序;
  • Throttling:限流。

Serializer

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "name", "email", "age"]

ViewSet

from rest_framework.viewsets import ModelViewSet

class UserViewSet(ModelViewSet):
    queryset = User.objects.filter(is_active=True)
    serializer_class = UserSerializer

Router

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register("users", UserViewSet)

urlpatterns = router.urls

它可以自动生成类似接口:

GET    /users/       查询列表
POST   /users/       创建记录
GET    /users/{id}/  查询详情
PUT    /users/{id}/  完整更新
PATCH  /users/{id}/  部分更新
DELETE /users/{id}/  删除记录

如果只需要查询,不允许修改,可使用:

from rest_framework.viewsets import ReadOnlyModelViewSet

class UserViewSet(ReadOnlyModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

21. 推荐的 Django 项目分层

一个较清晰的项目结构可以是:

project/
├── config/                 # 项目配置、根路由、ASGI/WSGI
│   ├── settings/
│   ├── urls.py
│   ├── asgi.py
│   └── wsgi.py
├── apps/
│   ├── users/
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── views.py
│   │   ├── urls.py
│   │   ├── services.py
│   │   ├── admin.py
│   │   └── tests/
│   └── orders/
├── manage.py
└── requirements.txt

业务复杂时建议分层:

View / Serializer
        ↓
Service(业务编排)
        ↓
Repository 或 ORM Query
        ↓
Model / Database

这样可避免把大量业务逻辑堆积在 View 中。


22. 常见开发命令

# 启动开发服务
python manage.py runserver

# 生成数据库迁移文件
python manage.py makemigrations

# 执行数据库迁移
python manage.py migrate

# 创建后台管理员
python manage.py createsuperuser

# 进入 Django 交互式环境
python manage.py shell

# 执行测试
python manage.py test

# 查看迁移状态
python manage.py showmigrations

23. Django 的适用场景

Django 很适合:

  • 企业内部管理系统;
  • SaaS 后台;
  • 运营平台;
  • 内容管理系统;
  • 电商和订单系统;
  • REST API 服务;
  • 用户、权限和组织结构复杂的系统;
  • 需要快速上线的业务平台。

它的优势是“自带电池”:ORM、认证、Admin、迁移、表单、缓存和安全能力都比较成熟。


24. 初学者最应掌握的顺序

建议按以下顺序学习:

1. Python 基础
2. HTTP、REST、JSON
3. Django 项目结构与 settings
4. URL 路由
5. 函数视图与类视图
6. Model 与 ORM
7. 数据库迁移
8. Django Admin
9. 用户认证和权限
10. Middleware、日志、异常处理
11. Django REST Framework
12. 缓存、事务、异步任务与性能优化

如果目标是做后端 API,可以优先掌握:

URL → View → Serializer → ORM → Authentication → Permission → Pagination → Filter

这条链路是 Django + DRF 日常开发最核心的部分。