还记得刚开始用Django写API接口时,你是怎么把数据库里的对象变成JSON返回给前端的吗?是不是经常像这样“徒手拆对象”?
import json
from django.http import JsonResponse
from myapp.models import Post
def post_list(request):
posts = Post.objects.all()
posts_list = []
for post in posts:
posts_list.append({
'id': post.id,
'title': post.title,
'content': post.content,
'created_at': post.created_at.isoformat()
})
return JsonResponse(posts_list, safe=False)
看着这一大坨循环和字段手动映射的代码,是不是感觉自己在做“数据搬运工”?别担心,今天我要给你安利的Django序列化器(Serializer),就是来解放你生产力的!
一、序列化器到底是什么来头?
简单来说,序列化器就是个超级专业的“数据翻译官”。它负责做两件事:
- 序列化:把Django模型对象(比如一个Post实例)→ 转换成前端能看懂的JSON数据
- 反序列化:把前端发来的JSON数据 → 转换成Django模型对象
想象一下,你有个会说中英双语的翻译官。当外国朋友(前端)用英语(JSON)跟你说话时,翻译官会立刻转成中文(Django对象)让你理解;等你用中文回复后,翻译官又会贴心地转成英语告诉对方。序列化器干的就是这个活儿!
二、为什么不用土办法,非要学序列化器?
你可能会问:我手写字典不是也能用吗?来,对比一下:
土办法的痛点:
- 字段多的时候,写到手软
- 日期格式、关联对象处理起来特别麻烦
- 前端传数据来时,要手动校验每个字段
- 代码重复,维护起来想哭
序列化器的爽点:
- 声明式写法,几行代码搞定复杂转换
- 自动处理各种数据类型和关联关系
- 内置数据验证,省去一堆if判断
- 代码简洁,维护起来so easy
最重要的是——当你开始用序列化器,就意味着你开始用更专业的方式构建API了!
三、手把手搭建博客API实战
咱们用一个完整的博客帖子API来实战。假设你已经有了基本的Django项目和Post模型:
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
第1步:创建你的“专属翻译官”——序列化器
在Django项目中创建一个serializers.py文件:
# serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post # 指定要翻译的模型
fields = ['id', 'title', 'content', 'created_at', 'updated_at'] # 要翻译的字段
看,就这么简单!ModelSerializer是Django REST Framework给我们的神器,自动根据模型生成对应的序列化器。
第2步:编写视图——告诉“翻译官”什么时候上场
接下来,我们用最常规的基于函数的视图,实现完整的CRUD操作:
# views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from .models import Post
from .serializers import PostSerializer
import json
# 获取所有帖子列表
@csrf_exempt
@require_http_methods(["GET"])
def post_list(request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True) # 多个对象要加many=True
return JsonResponse(serializer.data, safe=False)
# 获取单个帖子详情
@csrf_exempt
@require_http_methods(["GET"])
def post_detail(request, pk):
try:
post = Post.objects.get(pk=pk)
except Post.DoesNotExist:
return JsonResponse({'error': '帖子不存在'}, status=404)
serializer = PostSerializer(post)
return JsonResponse(serializer.data)
# 创建新帖子
@csrf_exempt
@require_http_methods(["POST"])
def post_create(request):
data = json.loads(request.body)
serializer = PostSerializer(data=data)
if serializer.is_valid(): # 自动校验数据!
serializer.save() # 自动创建对象!
return JsonResponse(serializer.data, status=201)
else:
return JsonResponse(serializer.errors, status=400)
# 更新帖子
@csrf_exempt
@require_http_methods(["PUT"])
def post_update(request, pk):
try:
post = Post.objects.get(pk=pk)
except Post.DoesNotExist:
return JsonResponse({'error': '帖子不存在'}, status=404)
data = json.loads(request.body)
serializer = PostSerializer(post, data=data) # 更新时要传入原对象
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
else:
return JsonResponse(serializer.errors, status=400)
# 删除帖子
@csrf_exempt
@require_http_methods(["DELETE"])
def post_delete(request, pk):
try:
post = Post.objects.get(pk=pk)
except Post.DoesNotExist:
return JsonResponse({'error': '帖子不存在'}, status=404)
post.delete()
return JsonResponse({'message': '删除成功'}, status=204)
第3步:配置路由
在urls.py中配置路由:
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('posts/', views.post_list, name='post_list'), # 获取列表和创建
path('posts/<int:pk>/', views.post_detail, name='post_detail'), # 单条操作
]
四、测试你的API
现在可以用Postman或curl测试了:
获取所有帖子:
GET http://localhost:8000/posts/
创建新帖子:
POST http://localhost:8000/posts/
Content-Type: application/json
{
"title": "我的第一篇博客",
"content": "这是用Django序列化器创建的!"
}
更新帖子:
PUT http://localhost:8000/posts/1/
Content-Type: application/json
{
"title": "修改后的标题",
"content": "更新了内容"
}
删除帖子:
DELETE http://localhost:8000/posts/1/
五、序列化器的进阶玩法
1. 数据验证——你的贴心安检员
序列化器会自动帮你验证数据。比如我们的Post模型要求title不能超过200字符,如果有人传了个超长的标题:
# 这会自动触发验证错误!
data = {
"title": "这个标题超级长..." * 50, # 明显超长
"content": "正常内容"
}
serializer = PostSerializer(data=data)
print(serializer.is_valid()) # False
print(serializer.errors) # 会显示title超长的错误信息
2. 字段控制——想显示啥就显示啥
有时候你不想把所有字段都暴露出去,比如更新日期可能不想返回给前端:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'content', 'created_at'] # 去掉了updated_at
或者只想在创建时跳过某些字段的验证:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__' # 包含所有字段
def validate_title(self, value):
if '广告' in value:
raise serializers.ValidationError("标题不能包含广告词")
return value
六、实际开发中的小贴士
- 性能优化:当查询列表时,记得使用
select_related或prefetch_related来避免N+1查询问题 - 错误处理:给前端返回统一的错误格式,比如:
{
"success": false,
"message": "创建失败",
"errors": {
"title": ["这个字段是必需的"],
"content": ["内容不能为空"]
}
}
- 分页处理:数据多了要分页,Django REST Framework有现成的分页器
七、总结
从今天起,彻底告别手动拼装JSON的苦日子吧!Django序列化器就像给你的项目请了个专业翻译官,让你能够:
✅ 用几行代码完成复杂的数据转换
✅ 自动获得数据验证,少写一堆if else
✅ 轻松维护,字段变更只需改一个地方
✅ 代码更专业,更符合RESTful规范
最重要的是,你终于可以从繁琐的数据搬运中解放出来,专注于更重要的业务逻辑了!
本文示例代码在Django 3.2 + Django REST Framework 3.12环境下测试通过。不同版本可能略有差异,但核心概念相通。

被折叠的 条评论
为什么被折叠?



