DRF 模型序列化器(ModelSerializer)

在 《DRF 序列化器(Serializer)》一文中已对 DRF 序列化器进行了介绍和演示,本篇文章将在上一篇基础上进一步介绍和演示模型序列化器(ModelSerializer),并附上演示案例

模型序列化器

模型序列化器可以对应 Django 的模型类,DRF 提供了ModelSerializer 模型序列化基类来快速创建一个模型序列化器。

ModelSerializerSerializer 额外提供了:

  • 基于模型类自动生成一系列字段
  • 基于模型类自动为 Serializer 生成 validators,比如 unique_together
  • 包含默认的 create()update() 的实现

模型序列化器的使用

构造方法

TestModelSerializer(instance=None,data=empty,**kwargs)
  • 用于序列化时,将模型类对象传入 instance 参数;

  • 用于反序列化时,将要被反序列化的数据传入 data 参数;

  • 除了 instancedata 参数外,在构造 Serializer 对象时,还可以通过 context 参数额外添加数据,通过 context 添加的数据,可以通过 Serializer 对象的 context 属性获取;

数据校验

extra_kwargs
validate

某个字段不属于指定的 model,它是 write_only ,需要用户传进来,但我们不能对它进行 save( ) ,因为 ModelSerializer 是基于 Model,这个字段在 Model 中没有对应,这个时候,我们需要重载 validate 进行验证后再数据清洗。

from rest_framework import serializers
class TestModelSerializer(serializers.ModelSerializer)
	class Meta:
        model = Test
    def validate(self, attrs):
        del attrs["code"]
        return attrs
UniqueTogetherValidator
  • queryset:required,用于明确验证唯一性集合,必须设置
  • fields: required,字段列表或者元组,字段必须是序列化类中存在的字段
  • message:当验证失败时的提示信息
  • UniqueTogetherValidator有一个隐性要求就是验证的字段必须要提供值,除非设置了一个默认值

SerializerMethodField

某个字段不属于指定的 model,它是 read_only,只需要将它序列化传递给用户,但是在这个 model中,没有这个字段时,需要用到 SerializerMethodField。比如,在数据库中储存了用户加入的日期,但是现在需要计算用户加入多久,就需要使用自定义的字段。

class TeacherModelSerializer(serializers.ModelSerializer):  
    days_since_joined = serializers.SerializerMethodField()
    # 方法写法:get_ + 字段
    def get_days_since_joined(self, obj):
    # obj指这个model的对象
        return (now() - obj.date_joined).days
 
    class Meta:
        model = Teacher

Demo

模型

# model.py
class Teacher(models.Model):
    name = models.CharField(
        null=False,
        max_length=255,
        verbose_name='姓名'
    )
    age = models.IntegerField(
        null=False,
        verbose_name='年龄'
    )
    sex = models.IntegerField(
        null=False,
        verbose_name='性别'
    )
    active = models.BooleanField(
        # 默认值为 True
        default=True,
        verbose_name='是否活跃'
    )
    description = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        verbose_name='描述'
    )
    date_joined = models.DateTimeField(
        default=timezone.now,
        verbose_name='加入时间'
    )

路由

from django.urls import path
from .views import TeacherView

urlpatterns = [
    path('teacher/<str:pk>', TeacherView.as_view()),
]

视图

# views.py
class TeacherView(APIView):
    def get(self, request, pk):
        """
        序列化器,序列化阶段的调用
        """
        if pk == 'all':
            # 1、获取数据集
            teacher_list = Teacher.objects.all()
            # 2、实例化序列化器,得到序列化对象
            serializer = TeacherModelSerializer(instance=teacher_list, many=True)
            # 3、调用序列化对象的data属性方法获取转换后的数据
            data = serializer.data
            # 4、响应数据
            return JsonResponse({'data': data, 'message': 'success'})
        else:
            query = Teacher.objects.filter(id=pk)
            if query.count():
                teacher = query.first()
                serializer = TeacherModelSerializer(instance=teacher)
                data = serializer.data
                return JsonResponse({'data': data, 'message': 'success'})
            else:
                return JsonResponse({'message': 'ID不存在'})

    def post(self, request, pk):
        """反序列化,采用字段选项来验证数据"""
        # 1、接收客户端提交的数据
        # 1.1 实例化序列化器,获取序列化对象
        data = request.data
        # 1.2 调用序列化对象验证数据
        serializer = TeacherModelSerializer(data=data)
        # 1.3 获取验证结果
        serializer.is_valid()  # 不抛出异常
        serializer.is_valid(raise_exception=True)  # 抛出异常
        # 2、操作数据
        serializer.save()
        # 3、返回数据
        return JsonResponse({'data': data, 'message': '添加成功'})

    def put(self, request, pk):
        """反序列化,采用字段选项来验证数据"""
        # 1、根据客户端提交的数据获取指定数据
        # 1.1 实例化序列化器,获取序列化对象
        pk = request.data.get('id', '')
        teacher = Teacher.objects.filter(id=pk).first()
        data = request.data
        # 1.2 调用序列化对象验证数据
        serializer = TeacherModelSerializer(instance=teacher, data=data)
        # 1.3 获取验证结果
        serializer.is_valid(raise_exception=True)  # 抛出异常
        # 2、操作数据
        # 会根据实例化序列化器的时候是否传入instance属性来自动调用create或者update方法,如果传入instance属性,调用update方法,没有传入instance属性,调用create方法
        serializer.save()
        # 3、返回数据
        return JsonResponse({'data': data, 'message': '修改成功'})

序列化器

# serializers.py
class TeacherModelSerializer(serializers.ModelSerializer):
    class Meta:
        # 1、指定对应的 Django 模型,必填
        model = Teacher
        # 2、声明转换字段必填,如果需要全部转换可以设置为 __all__
        # fields = '__all__'
        fields = ["id", "name", "age", "sex", "classmate", "nickname"]
        # read_only_fields指明只读字段,即仅用于序列化输出的字段
        read_only_fields = ['id', 'date_joined']
        # 也可以使用exclude可以明确排除掉哪些字段
        # exclude = ['id']
        # 字段额外选项信息,如错误的提示信息,选填
        extra_kwargs = {
            "name": {
                'required': True
            },
            "age": {
                "max_value": 20,
                "min_value": 5,
                "error_messages": {
                    "max_value": "must younger than 20",
                    "min_value": "must older than 5",
                }
            }
        }

    # 全局钩子
    def validate(self, attrs):
        """
        验证来自客户端的所有字段
        """
        if not attrs['active'] and attrs['description']:
            raise serializers.ValidationError(
                detail='非active老师需要添加描述',
                code='validate'
            )
        return attrs
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DRFDjango Rest Framework)是一种用于构建Web API的强大框架,它提供了丰富的功能和工具来简化API的开发过程。在使用DRF时,我们经常需要定义视图和序列化以及它们之间的关系来处理不同的请求和操作。 DRF的请求处理基于视图的操作方法,它们分别对应于HTTP方法,例如GET,POST,PUT,PATCH和DELETE。这些操作方法在视图中以函数的形式定义,并且通过装饰或路由来映射到相应的URL。 序列化DRF的一个核心概念,它提供了一种简单而灵活的方式,将数据对象转换为可以被序列化和反序列化的格式,通常是JSON或XML。序列化可以定义在视图中,也可以单独定义为一个类,然后在视图中使用。 在DRF中,我们可以通过定义不同的序列化类来处理不同的操作。序列化类可以继承自DRF提供的Serializer类或ModelSerializer类,后者自动为我们根据模型生成序列化字段。 使用序列化,我们可以在视图中方便地对请求进行验证、数据转换和结果序列化等操作。在视图的操作方法中,我们可以通过调用序列化的不同方法来进行这些操作。 例如,我们可以使用序列化的`is_valid()`方法来验证请求的数据是否有效。我们还可以使用`save()`方法来保存数据,或者使用`data`属性来获取序列化后的数据。此外,我们还可以通过调用`serializer_class()`方法来获取当前视图使用的序列化类。 总之,DRF的action序列化提供了一种方便而强大的方式来处理API的请求和操作。通过定义视图和序列化,并将它们联系起来,我们可以在开发API时更加高效和灵活。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值