Django基础教程(九十四)Django序列化之开始编写Web API:别再用土办法传数据了!Django REST Framework带你优雅“搞API”,代码香到后端哭出声

第一章:开篇暴击——我们为啥要“序列化”?

哥们儿,想象一下这个场景。你,一个充满理想(但有点脱发)的后端开发者,接到了一个需求:“给前端APP搞个接口,拉一下用户列表。”

你邪魅一笑,心想这还不简单?反手就在Django的视图里写下:

from django.http import JsonResponse
from .models import User

def user_list(request):
    users = User.objects.all()
    user_list = []
    for user in users:
        user_list.append({
            'id': user.id,
            'name': user.name,
            'email': user.email,
            # ... 如果字段有20个,你是不是要写到下班?
        })
    return JsonResponse(user_list, safe=False)

代码跑起来了,数据也返回了。但你怎么看怎么觉得……土!

这种感觉就像,你要给朋友寄一份精心准备的礼物,结果找了个破蛇皮袋来装。礼物本身很棒,但这包装也太掉价了!而且,万一礼物是个易碎品(比如复杂的关系数据),这蛇皮袋分分钟给你碎一地。

这里的“蛇皮袋”,就是你手动构建字典和列表的过程。它有几个致命伤:

  1. 累死个人:模型有20个字段,你就要手动写20次。ORM帮你省下的时间,全搭在这儿了。
  2. 极易出错:手打字段名,usr_nameuser_name 傻傻分不清楚,一个字母就能让你debug半小时。
  3. 维护地狱:今天加个字段,明天删个字段,你得同时在模型和这个视图里修改,一不小心就忘了。
  4. 不够“RESTful”:现代的Web API讲究一个规范,比如状态码、错误信息格式、关联数据的处理。靠手拼?太难统一了!

所以,我们需要一个“礼物包装大师”,一个能把我们的Django模型(或者说,任何Python数据结构)优雅地、安全地、转换成JSON/XML等格式的神器

这个神器,就是 Django REST Framework(后面我们亲切地称它为DRF)。而它的核心魔法,就叫 “序列化”


第二章:请出我们的Super Star——Django REST Framework

DRF,它不是Django的亲儿子,但绝对是比亲儿子还受宠的“干儿子”。它是一个强大而灵活的Web API工具包,专门为Django而生。

在开始“烹饪”API大餐之前,我们先得准备好厨房和食材。

步骤零:安装与配置

pip install djangorestframework

然后,在你的settings.py文件里,把它加入到INSTALLED_APPS中。

INSTALLED_APPS = [
    ...
    'rest_framework', # 新增这一行
]

这就好比,你买了顶级厨具,并且把它放进了厨房,随时可以开火!


第三章:灵魂所在——序列化器初体验

序列化器,是DRF的灵魂。它干两件核心大事:

  1. 序列化:把数据库里取出来的、复杂的模型实例(QuerySet),变成前端能看懂的JSON数据。(就像把Python对象打包成快递盒)
  2. 反序列化:把前端传过来的JSON数据,验证通过后,变成可以存入数据库的Python对象。(就像拆开快递,检查物品完好,再入库)

我们来搞一个真实的例子。假设我们正在开发一个“智障待办事项”应用,它的模型Todo长这样:

models.py

from django.db import models

class Todo(models.Model):
    STATUS_CHOICES = (
        ('todo', '待处理'),
        ('doing', '进行中'),
        ('done', '已完成'),
    )
    
    title = models.CharField(max_length=200, verbose_name="标题")
    description = models.TextField(blank=True, verbose_name="详细描述")
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='todo', verbose_name="状态")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    def __str__(self):
        return self.title

现在,我们要为这个Todo模型创建一个专属的序列化器。

serializers.py(在app目录下新建这个文件)

from rest_framework import serializers
from .models import Todo

# 这就是我们的“礼物包装大师”!
class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo # 告诉序列化器,它是为哪个模型服务的
        fields = '__all__' # 最简单粗暴的方式:序列化模型的所有字段
        # fields = ['id', 'title', 'status', 'created_at'] # 你也可以选择只序列化部分字段

看!ModelSerializer 这个类就是这么霸道总裁。你只需要在Meta类里告诉它模型是谁,要哪些字段,它就能自动帮你生成一套完整的序列化规则。

fields = '__all__' 相当于说:“老板,全都要!”


第四章:从“能用”到“好用”——视图的终极进化

有了包装大师(序列化器),我们还得有个“前台”来接单和派单。这个前台,就是视图。

在DRF里,写视图有几种姿势,我们从普通到开挂,一步步来。

姿势一:APIView(基础版,有控制感)

这类似于Django的View,但更强大,专门为API而生。

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Todo
from .serializers import TodoSerializer

class TodoListAPIView(APIView):
    """
    处理 /api/todos/ 这个地址的请求
    """
    
    def get(self, request):
        """获取所有待办事项"""
        todos = Todo.objects.all()
        serializer = TodoSerializer(todos, many=True) # 序列化多个对象,要加 many=True
        return Response(serializer.data) # Response 比 JsonResponse 更强大
    
    def post(self, request):
        """创建一个新的待办事项"""
        serializer = TodoSerializer(data=request.data)
        if serializer.is_valid(): # 自动调用验证!这才是专业操作!
            serializer.save() # 自动保存到数据库!
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # 验证失败,返回错误信息

姿势二:GenericAPIView + Mixins(进阶版,少写代码)

DRF觉得你上面那样写还是太啰嗦,于是提供了Mixins,把get, post这些通用逻辑都给你写好了。

views.py

from rest_framework import generics, mixins
from .models import Todo
from .serializers import TodoSerializer

class TodoListCreateView(mixins.ListModelMixin,
                         mixins.CreateModelMixin,
                         generics.GenericAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs) # 直接调用混入的list方法

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs) # 直接调用混入的create方法

姿势三:ViewSet(终极开挂版,yyds!)

ViewSet 把一组相关的操作(比如对Todo的增删改查)全部打包在一起。它通常和Routers配合使用,能让你用几行代码就生成一套完整的CRUD API!

views.py

from rest_framework import viewsets
from .models import Todo
from .serializers import TodoSerializer

# 就这?就这!一行类定义,搞定所有事!
class TodoViewSet(viewsets.ModelViewSet):
    queryset = Todo.objects.all().order_by('-created_at') # 获取所有数据,按创建时间倒序排
    serializer_class = TodoSerializer # 指定使用的序列化器

这个TodoViewSet,等价于你手动写了list, create, retrieve(获取单个), update, partial_update, destroy 所有这些方法!

配置URL(见证奇迹的时刻)

urls.py

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import TodoViewSet

router = DefaultRouter() # 创建一个默认的路由器
router.register(r'todos', TodoViewSet) # 注册我们的ViewSet

urlpatterns = [
    path('api/', include(router.urls)), # 把路由器生成的所有URL,都包含到 /api/ 路径下
]

启动你的开发服务器(python manage.py runserver),然后访问 http://127.0.0.1:8000/api/todos/

噔噔!一个功能齐全、界面美观、自带文档的API列表页面就出现了!

你可以直接在这个页面上点击“POST”按钮创建新待办,可以点进详情进行修改或删除。这一切,我们几乎没怎么写视图逻辑!这就是DRF + ViewSet + Router的组合拳威力!


第五章:完整示例——我们的“智障待办”API全家桶

让我们把上面的代码碎片拼凑起来,形成一个完整的、可运行的例子。

  1. 模型 models.py:上面已经定义好了。
  2. 序列化器 serializers.py
from rest_framework import serializers
from .models import Todo

class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = '__all__'
  1. 视图 views.py
from rest_framework import viewsets
from .models import Todo
from .serializers import TodoSerializer

class TodoViewSet(viewsets.ModelViewSet):
    queryset = Todo.objects.all().order_by('-created_at')
    serializer_class = TodoSerializer
  1. URL配置 urls.py(项目主urls.py):
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('yourapp.urls')), # 假设你的app名叫 'yourapp'
]

yourapp/urls.py:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import TodoViewSet

router = DefaultRouter()
router.register(r'todos', TodoViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

现在,你的API已经拥有了以下所有端点,且完全符合RESTful风格:

  • GET /api/todos/ - 获取所有待办列表
  • POST /api/todos/ - 创建一个新待办
  • GET /api/todos/{id}/ - 获取一个待办的详情
  • PUT /api/todos/{id}/ - 更新一个待办的所有字段
  • PATCH /api/todos/{id}/ - 部分更新一个待办
  • DELETE /api/todos/{id}/ - 删除一个待办
第六章:总结——拥抱DRF,告别手工作坊

回头看看我们最开始那个“手拼JSON”的土办法,是不是感觉像从石器时代穿越回来的?

DRF通过序列化器这个核心概念,帮你完成了最繁琐、最容易出错的数据转换和验证工作。又通过 ViewSetRouter 这套“最佳实践组合”,让你用极简的代码,生成出规范、健壮、可维护的RESTful API。

它给你的,不仅仅是一个工具,更是一种现代化的开发理念和工作流。从此,你可以把宝贵的时间和头发,用在更复杂的业务逻辑上,而不是在“字段名拼写错误”这种坑里反复横跳。

所以,还等什么?赶紧把DRF用起来,让你的后端代码也变得优雅、专业、并且香到让同事羡慕哭吧!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值