Django Serializer 优化类视图:Create 与 Update 方法重构

林舟
林舟
发布时间:2026-10-14 | 2人浏览过
原创

本文详解 Django 中 Serializer 在类视图中的优化技巧。通过合并序列化器对象,利用 save() 方法自动调用 create 和 update 逻辑,简化视图代码。重点讲解如何重写父类 create 和 update 方法,实现数据校验与数据库操作的无缝衔接,并提供 Postman 验证结果及额外参数传递技巧。

Create 方法优化

一、Create 方法优化

在 Django 序列化器(Serializer)的使用中,通过实例化序列化器对象可以显著简化视图函数的逻辑。前端提交的数据会经过反序列化过程中的各项校验,具体实现代码如下:


from django.http import JsonResponse
from django.views import View
import json
from .models import Project
from .serializers import ProjectsSerializer


class ProjectsPage(View):
  '''
  类视图
  '''
  def post(self, request):

    input_data = json.loads(request.body)

    serializer_obj = ProjectsSerializer(data=input_data)

    if not serializer_obj.is_valid():
      return JsonResponse({"code": 1, "res": "error", "msg": serializer_obj.errors})

    obj = Project.objects.create(**input_data)

    ser_obj = ProjectsSerializer(instance=obj)

    return JsonResponse(ser_obj.data, status=201)

从代码可见,初始实现中创建了两个序列化器实例:`serializer_obj` 用于接收前端参数进行反序列化校验(通过 `data` 参数),而 `ser_obj` 用于将模型对象序列化为输出数据(通过 `instance` 参数)。实际上,可以省略第二个实例 `ser_obj`,直接调用第一个实例的 `save()` 方法。该方法会自动触发序列化器中定义的 `create` 逻辑,从而简化代码结构。


def post(self, request):
    """
    post请求,新增数据
    :param request:
    :return:
    """
    try:

      data = json.loads(request.body, encoding='utf-8')
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    ser_obj = ProjectsSerializer(data=data)
    try:
      ser_obj.is_valid(raise_exception=True)
    except Exception as e:
      result = {"msg": "参数有误"}
      result.update(ser_obj.errors)
      return JsonResponse(result, status=400)

    ser_obj.save()

    resp = {"msg": "创建成功"}
    resp.update(ser_obj.data)

    return JsonResponse(resp, status=201)

为了支持上述优化,序列化器类中必须预先定义 `create` 方法。该方法用于重写父类的默认行为,其父类源码如下:


def create(self, validated_data):
    return [
      self.child.create(attrs) for attrs in validated_data
    ]

我们需要在自定义序列化器中重写父类的 `create` 方法,并确保其返回模型类对象,以便后续序列化输出。


 def create(self, validated_data):

    obj = Project.objects.create(**validated_data)

    return obj

使用 Postman 工具对优化后的接口进行验证,结果如下:


成功写入数据库的数据记录如下:


Update 方法优化

二、Update 方法优化


def put(self, request, pk):
    try:
      obj = Project.objects.get(id=pk)
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    update_data = json.loads(request.body)

    serializer_obj = ProjectsSerializer(data=update_data)
    if not serializer_obj.is_valid():
      return JsonResponse({"code": 1, "res": "error", "msg": serializer_obj.errors})

    obj.name = serializer_obj.validated_data.get('name') or obj.name
    obj.leader = serializer_obj.validated_data.get('leader') or obj.leader
    obj.desc = serializer_obj.validated_data.get('desc') or obj.programmer
    obj.tester = serializer_obj.validated_data.get('tester') or obj.tester
    obj.save()

    ser_obj = ProjectsSerializer(instance=obj)

    return JsonResponse(ser_obj.data, status=201)

针对更新操作,之前创建的两个序列化器对象可以进一步合并。与 `create` 略有不同,这里需要在实例化序列化器时同时传入 `data`(前端更新数据)和 `instance`(待更新的模型对象)。随后调用 `save()` 方法,系统会自动调用序列化器中定义的 `update` 逻辑。优化后的 PUT 方法代码如下:


  def put(self, request, pk):
    try:
      obj = Project.objects.get(id=pk)
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    request_data = request.body

    try:
      python_data = json.loads(request_data)
    except Exception as e:
      result = {
        "msg": "参数有误",
        "code": 0
      }
      return JsonResponse(result, status=400)

    serializer_obj = ProjectsSerializer(instance=obj, data=python_data)
    try:
      serializer_obj.is_valid(raise_exception=True)
    except Exception as e:
      resp = {'msg': '参数有误'}
      resp.update(serializer_obj.errors)
      return JsonResponse(resp, status=400)

    serializer_obj.save()
    resp = {'msg': '修改成功'}
    resp.update(serializer_obj.data)

    return JsonResponse(resp, status=201)

同样,序列化器类中需要预先定义 `update` 方法以重写父类行为。父类的默认实现源码如下:


 def update(self, instance, validated_data):
    raise_errors_on_nested_writes('update', self, validated_data)
    info = model_meta.get_field_info(instance)
    m2m_fields = []
    for attr, value in validated_data.items():
      if attr in info.relations and info.relations[attr].to_many:
        m2m_fields.append((attr, value))
      else:
        setattr(instance, attr, value)
    instance.save()
    for attr, value in m2m_fields:
      field = getattr(instance, attr)
      field.set(value)

    return instance

在自定义序列化器中重写 `update` 方法,处理字段更新逻辑并返回模型对象。注意:原文中拼写为 `updata`,此处修正为标准的 `update`。


 def update(self, instance, validated_data):
    """
    更新数据
    :param instance: 待更新的模型类对象
    :param validated_data: 校验通过之后的数据
    :return: 模型类对象
    """
    instance.name = validated_data.get('name') or instance.name
    instance.leader = validated_data.get('leader') or instance.leader
    instance.tester = validated_data.get('tester') or instance.tester
    instance.desc = validated_data.get('desc') or instance.desc
    instance.save()
    return instance

使用 Postman 对更新接口进行验证,结果如下:



补充提示:在调用序列化器对象的 `save()` 方法时,可以通过关键字参数传递额外信息。这些参数会自动合并到 `create` 方法的 `validated_data` 中。典型应用场景包括:在创建项目时自动关联当前操作用户,实现“判断当前项目由哪个用户创建”的功能。

至此,关于 Django Serializer 优化类视图的实现示例介绍完毕。如需了解更多相关技术细节,可查阅本站过往文章或继续浏览后续内容。感谢大家的支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表