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 的职责是:
- 接收请求;
- 读取参数;
- 调用业务逻辑;
- 查询或更新数据;
- 返回 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 日常开发最核心的部分。