DRF框架(五)——serializer序列化组件

序列化组件

目录

序列化组件

知识点:

使用:

一、序列化用户表设计

二、序列化组件使用

三、自定义序列化属性

四、反序列化组件使用

总结

一、Serializer的构造方法:

二、序列化器的使用

 


知识点:

  • Serializer(偏底层)、ModelSerializer(重点)、ListModelSerializer(辅助群改)
  • 作用:视图中查询到的对象和queryset类型不能直接作为数据返回给前台,所以使用序列化组件

 

使用实例:

一、序列化用户表设计

编写models.py

from django.db import models


class User(models.Model):
    SEX_CHOICES = [
        [0, '男'],
        [1, '女'],
    ]
    name = models.CharField(max_length=64)
    pwd = models.CharField(max_length=32)
    phone = models.CharField(max_length=11, null=True, default=None)
    sex = models.IntegerField(choices=SEX_CHOICES, default=0)
    icon = models.ImageField(upload_to='icon', default='icon/default.jpg')

    class Meta:
        db_table = 'old_boy_user'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

    # 规范格式
    def __str__(self):
        return '%s' % self.name

二、序列化组件使用

  • 序列化提供给前台的数据由后台决定,可以少提供
  • 但是提供的数据库对应的字段,名字一定要与数据库字段相同

创建文件 serializer.py

# 序列化组件 - 为每一个model类提供一套序列化工具类
# 序列化组件的工作方式于Django froms组件非常相似
from rest_framework import serializers

class UserSerializer(serializers.Serializer):
    name = serializers.CharField()
    phone = serializers.CharField()
    sex = serializers.IntegerField()
    icon = serializers.ImageField()


编写 views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers


class User(APIView):
    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            try:
                # 用户对象不能直接作为数据返回给前台
                user_obj = models.User.objects.get(pk=pk)
                # 序列化一下用户对象
                user_ser_data = serializers.UserSerializer(user_obj).data
                return Response({
                    'status': 0,
                    'msg': 0,
                    'result': user_ser_data
                })
            except:
                return Response({
                    'status': 2,
                    'msg': '用户不存在',
                })
        else:
            # 用户对象列表(queryset)不能直接作为数据返回给前台
            user_obj_list = models.User.objects.all()
            # 序列化一下用户对象列表
            user_ser_data = serializers.UserSerializer(user_obj_list, many=True).data
            return Response({
                'status': 0,
                'msg': 0,
                'result': user_ser_data
            })

运行结果:

三、自定义序列化属性

编辑 serializers.py

from rest_framework import serializers
from django.conf import settings


class UserSerializer(serializers.Serializer):
    name = serializers.CharField()
    phone = serializers.CharField()

    # 自定义序列化属性
    # 属性名随意,值由固定的命名规范方法提供:
    #       get_属性名(self, 参与序列化的model对象)
    #       返回值就是自定义序列化属性的值
    gender = serializers.SerializerMethodField()
    def get_gender(self, obj):
        return obj.get_sex_display()


    icon = serializers.SerializerMethodField()
    def get_icon(self, obj):
        # settings.MEDIA_URL,自己配置的/media/,给后面高级序列化与视图准备的
        # obj.icon不能直接作为数据返回,因为内容虽然是字符串,但是类型是ImageFieldFile类型
        return '%s%s%s'% (r'http://127.0.0.1:8000', settings.MEDIA_URL, str(obj.icon))

运行结果:

四、反序列化组件使用

  • 哪些字段必须反序列化
  • 字段都有哪些安全校验
  • 哪些字段需要额外提供校验
  • 哪些字段间存在联合校验
  • 反序列化字段都是用来入库的,不会出现自定义属性

编写serializers.py

from rest_framework import serializers
from django.conf import settings

class UserDeserializer(serializers.Serializer):
    name = serializers.CharField()
    pwd = serializers.CharField()
    phone = serializers.CharField()

 

编写views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from . import models, serializers


class User(APIView):
    # 只考虑单增
    def post(self, request, *args, **kwargs):
        request_data = request.data
        # 数据是否合法(增加对象需要一个字典数据)
        if not isinstance(request_data, dict) or request_data == {}:
            return Response({
                'status': 1,
                'msg': '数据有误'
            })
        # 数据类型合法,但数据内容不一定合法,需要校验数据
        book_ser = serializers.UserDeserializer(data=request_data)

        if book_ser.is_valid():
            # 校验通过,完成新增
            book_obj = book_ser.save()
            return Response({
                'status': 0,
                'msg': 'ok',
                'result': serializers.UserDeserializer(book_obj).data
            })
        else:
            # 校验失败
            return Response({
                'status': 1,
                'msg': book_ser.errors,
            })

        return Response({
            'status': 0,
            'msg': 'ok'
        })

 

总结

一、Serializer的构造方法:

Serializer(instance=None, data=empty, **kwargs)

1)、使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。

2)、序列化器无法直接接受数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。(data,instance传参)

  • 序列化:数据对象从数据库中查出,通过instance传入序列化器中,必须通过data属性才能将序列化后的数据传给前端,不能直接传序列化对象
  • 反序列化:数据是通过request.data从前端获取到数据,通过data传入序列化器中进行校验,保存到数据库中

3)、开发restful api时,序列化器会帮我们把模型数据转换成字典。

4)、drf提供的视图会帮我们把字典转换成json,或者把客户端发过来的数据转换成字典。

 

二、序列化器的使用

序列化器的使用分两个阶段:

1、在客户端请求时:使用序列化器可以完成对数据的反序列化(就是前端往后端传递数据,反序列化之后保存数据)。

2、在服务器响应时,使用序列化器可以完成对数据的序列化(服务器取出数据,序列化之后往前端发送展示)。

 

序列化使用流程:

1、先查询出一个用户对象

from models import user
user = User.object.get(id=2)

2、构造序列化器对象

from user.serializers import UserSerializer
user_obj = Userserializer(user) #放入查询出的user对象

3、获取序列化对象 通过data属性可以获取序列化后的数据

user_ser = Userserializer(user).data

4、如果要被序列化的数据是包含多条数据的,需要添加many=True参数

user = models.User.objects.all()
user_ser = Userserialzier(user, many=True)

5、自定义序列化属性(重点)

serializers.SerializerMethodField()

 

反序列化使用流程:

数据验证:

1、使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象

2、在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False

3、验证失败,可以通过序列化对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误

4、验证通过,可以通过序列化器对象的validated_data属性获取数据

 

保存数据:

视图中使用create()和save()方法

序列化类中必须重写create方法用户新增,重写update方法是修改

  • 从源码可知save()方法内部调用的是序列化类中的create方法,所以新增必须要在序列化类中重写create方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值