zoukankan      html  css  js  c++  java
  • drf序列化器与反序列化

    什么是序列化与反序列化

    """
    序列化:对象转换为字符串用于传输
    反序列化:字符串转换为对象用于使用
    """
    

    drf序列化与反序列化

    """
    序列化:Model类对象转换为字符串用于传输
    反序列化:字符串转换为Model类对象用于使用
    """
    

    Model类

    创建数据库:终端
    >: mysql -uroot -p密码
    >: create database 数据库名 charset=utf8
    
    配置数据库:settings.py
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': '数据库名',
            'USER': 'root',
            'PASSWORD': '密码'
        }
    }
    
    修改操作数据库的模块:项目init文件
    import pymysql
    pymysql.install_as_MySQLdb()
    
    创建model类:models.py
    from django.db import models
    class User(models.Model):
        CHOICE_SEX = (
            (0, '男'),
            (1, '女')
        )
        name = models.CharField(max_length=32, verbose_name='姓名')
        password = models.CharField(max_length=64, verbose_name='密码')
        sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0)
        create_time = models.DateTimeField(auto_now_add=True, blank=True)
    
        class Meta:
            # 自定义创建的表名
            db_table = 'o_user'
            # admin界面中显示的表面与表名复数形式
            verbose_name = '用户'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    注册model类:admin.py
    from django.contrib import admin
    from api.models import User
    admin.site.register(User)
    
    数据库迁移:在项目目录下的终端
    >: python3 manage.py makemigrations
    >: python3 manage.py migrate
    
    注册超级用户:在项目目录下的终端
    >: python3 manage.py createsuperuser
    
    登陆admin页面添加数据:浏览器
    http://localhost:8000/admin/
    

    路由分发

    项目urls.py
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/', include('api.urls'))
    ]
    
    api应用urls.py
    from django.conf.urls import url
    urlpatterns = [
    
    ]
    

    获取多资源 接口

    序列化类:serializers.py
    from rest_framework import serializers
    
    # 为每一个Model类至少配一个Serializer类
    class UserSerializer(serializers.Serializer):
        # 序列化一个Model类对象,其实就是序列化该类的每一个属性
        name = serializers.CharField()
        password = serializers.CharField()
        sex = serializers.IntegerField()
        create_time = serializers.DateTimeField()
    
    视图类:views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import User
    from .serializers import UserSerializer
    
    # 对应路由:/users/
    # 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个
    class UsersAPIView(APIView):
        def get(self, request, *args, **kwargs):
            user_list = User.objects.all()
    		
            # instance存放的是queryset对象,many需要设置为True
            user_data = UserSerializer(instance=user_list, many=True).data
            return Response(
                {
                    'status': 0,
                    'msg': 'ok',
                    'results': user_data
                }
            )
    

    序列化字段操作(自定义字段)

    序列化类修订:serializers.py
    from rest_framework import serializers
    
    # 为每一个Model类至少配一个Serializer类
    class UserSerializer(serializers.Serializer):
        # 序列化一个Model类对象,其实就是序列化该类的每一个属性
        # 注意1:Model类与Serializer类是通过属性名建立关联的 - 属性名必须依照
        name = serializers.CharField()
        password = serializers.CharField()
        # sex = serializers.IntegerField()
        # 注意2:不需要通过给前台的数据,不需要提供该属性的序列化
        # create_time = serializers.DateTimeField()
    
        # 注意3:serializers.SerializerMethodField()可以产生自定义序列化属性(不需要和Model类属性同步),
        #       但要为其绑定一个提供值的函数,函数名为 get_属性(self, obj) (obj为参与序列化的Model类对象)
        gender = serializers.SerializerMethodField()
        def get_gender(self, obj):
            # 该函数的返回值就作为对应自定义数据序列化后的值
            return obj.get_sex_display()
    

    新增单资源 接口

    序列化类(反序列化类):serializers.py
    from rest_framework import serializers
    from .models import User
    
    
    class UserDeserializer(serializers.Serializer):
        name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={
            'max_length': '姓名太长',
            'min_length': '姓名太短'
        })
        password = serializers.CharField(label='密码', max_length=64, min_length=3, error_messages={
            'max_length': '密码太长',
            'min_length': '密码太短'
        })
        sex = serializers.IntegerField()
        # required=False该字段前台可以不用传(不参与校验)
        create_time = serializers.DateTimeField(required=False)
    
        # 完成ORM的操作
        # def save(self):  # 不能直接重写save,因为系统的save可以完成新增或修改
        #     # print(self.validated_data)
        #     User.objects.create(**self.validated_data)
    
        # 为post接口提供新增Model类对象的功能
        def create(self, validated_data):
            # 返回值:Model类要新增的对象
            return User.objects.create(**validated_data)
    
    视图类:views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import User
    from .serializers import UserSerializer
    
    # 对应路由:/users/
    # 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个
    class UsersAPIView(APIView):
        # 新增一个资源
        def post(self, request, *args, **kwargs):
            user_deser = UserDeserializer(data=request.data)
            # raise_exception值为True,当校验失败,直接返回校验失败的错误信息
            # result = user_deser.is_valid(raise_exception=True)
            result = user_deser.is_valid()
            if result:
                new_user_obj = user_deser.save()
                return Response({
                    'status': 0,
                    'msg': 'success',
                    'result': UserSerializer(new_user_obj).data
                })
            else:
                return Response({
                    'status': 1,
                    'msg': 'failed',
                    'results': user_deser.errors
                })
    
    
    

    更新单资源 接口

    序列化类(反序列化类):serializers.py
    from rest_framework import serializers
    from .models import User
    
    
    class UserDeserializer(serializers.Serializer):
        name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={
            'max_length': '姓名太长',
            'min_length': '姓名太短'
        })
        password = serializers.CharField(label='密码', max_length=64, min_length=3, error_messages={
            'max_length': '密码太长',
            'min_length': '密码太短'
        })
        sex = serializers.IntegerField()
        # required=False该字段前台可以不用传(不参与校验)
        create_time = serializers.DateTimeField(required=False)
    
        # 完成ORM的操作
        # def save(self):  # 不能直接重写save,因为系统的save可以完成新增或修改
        #     # print(self.validated_data)
        #     User.objects.create(**self.validated_data)
    
        # 为post接口提供新增Model类对象的功能
        def create(self, validated_data):
            # 返回值:Model类要新增的对象
            return User.objects.create(**validated_data)
        
        # 为put接口提供更新Model类对象的功能
        def update(self, instance, validated_data):
            # 操作model对象
            # instance.name = validated_data.get('name')
            # instance.password = validated_data.get('password')
            # instance.sex = validated_data.get('sex')
            # instance.save()
            # 操作queryset对象
            instance.update(**validated_data)
            return instance
    
    视图类:views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import User
    from .serializers import UserSerializer
    
    # 对应路由:/users/
    # 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个
    class UsersAPIView(APIView):
    	# 更新一个资源
        def put(self, request, *args, **kwargs):
            # 要更新的资源的主键
            pk = kwargs.get('pk')
    		
            # 操作更新时可以选择操作 queryset对象 或 model对象
    		# 操作model对象
            # old_user_obj = User.objects.get(pk=pk)
            # user_deser = UserDeserializer(instance=old_user_obj, data=request.data)
    
            # 操作queryset对象
            old_user_query = User.objects.filter(pk=pk)
            user_deser = UserDeserializer(instance=old_user_query, data=request.data)
    
            # raise_exception值为True,当校验失败,直接返回校验失败的错误信息
            # result = user_deser.is_valid(raise_exception=True)
            result = user_deser.is_valid()
            if result:
                # new_user_obj = user_deser.save()  # 操作model对象
                new_user_query = user_deser.save()  # 操作queryset对象
                new_user_obj = new_user_query.first()
                return Response({
                    'status': 0,
                    'msg': 'success',
                    'result': UserSerializer(new_user_obj).data
                })
            else:
                return Response({
                    'status': 1,
                    'msg': 'failed',
                    'results': user_deser.errors
                })
    

    删除单资源 接口

    重构Model新增字段:models.py
    class User(models.Model):
        CHOICE_SEX = (
            (0, '男'),
            (1, '女')
        )
        name = models.CharField(max_length=32, verbose_name='姓名')
        password = models.CharField(max_length=64, verbose_name='密码')
        sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0)
        create_time = models.DateTimeField(auto_now_add=True, blank=True)
        # 新增:数据删除不是从数据库删除记录,而是修改记录状态,标示为已删除即可
        is_delete = models.BooleanField(default=False)
    
        class Meta:
            # 自定义创建的表名
            db_table = 'o_user'
            # admin界面中显示的表面与表名复数形式
            verbose_name = '用户'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    数据库迁移:在项目目录下的终端
    >: python3 manage.py makemigrations
    >: python3 manage.py migrate
    
    视图类接口:views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import User
    from .serializers import UserSerializer
    
    # 对应路由:/users/
    # 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个
    class UsersAPIView(APIView):
    	# 删除一个资源
        def delete(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            try:
                delete_user_obj = User.objects.get(pk=pk, is_delete=False)
                # 完成删除信息的更新
                delete_user_obj.is_delete = True
                delete_user_obj.save()
                return Response()
            except:
                return Response({
                    'status': 1,
                    'msg': '数据删除失败'
                })
    

    获取单资源 接口

    序列化类:serializers.py
    from rest_framework import serializers
    
    # 为每一个Model类至少配一个Serializer类
    class UserSerializer(serializers.Serializer):
        # 序列化一个Model类对象,其实就是序列化该类的每一个属性
        name = serializers.CharField()
        password = serializers.CharField()
        sex = serializers.IntegerField()
        create_time = serializers.DateTimeField()
    
    视图类:views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import User
    from .serializers import UserSerializer
    
    # 对应路由:/users/
    # 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个
    class UsersAPIView(APIView):
        def get(self, request, *args, **kwargs):
             pk = kwargs.get('pk', None)
    
            if not pk:
                user_query = User.objects.filter(is_delete=False).all()
            else:
                user_query = User.objects.filter(is_delete=False, pk=pk)
                # 如果只操作一个对象,many参数需要为False(默认值)
                # user_obj = User.objects.filter(is_delete=False, pk=pk).first()
                # user_data = UserSerializer(instance=user_obj, many=False).data
    
            user_data = UserSerializer(instance=user_query, many=True).data
            return Response(
                {
                    'status': 0,
                    'msg': 'ok',
                    'results': user_data
                }
            )
    

    序列化基础:重点内容

    模型类:models.py
    from django.db import models
    
    # Create your models here.
    
    class User(models.Model):
        CHOICE_SEX = (
            (0, '男'),
            (1, '女')
        )
        name = models.CharField(max_length=32, verbose_name='姓名')
        password = models.CharField(max_length=64, verbose_name='密码')
        sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0)
        create_time = models.DateTimeField(auto_now_add=True, blank=True)
        # 数据删除不是从数据库删除记录,而是修改记录状态,标示为已删除即可
        is_delete = models.BooleanField(default=False)
    
        class Meta:
            # 自定义创建的表名
            db_table = 'o_user'
            # admin界面中显示的表面与表名复数形式
            verbose_name = '用户'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    序列化类:
    from rest_framework import serializers
    from .models import User
    
    class UserSerializer(serializers.Serializer):
        # 序列化和反序列化都可以使用
        name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={
            'max_length': '姓名太长',
            'min_length': '姓名太短'
        })
        password = serializers.CharField(label='密码', max_length=64, min_length=3, error_messages={
            'max_length': '密码太长',
            'min_length': '密码太短'
        })
        # 只有反序列化使用 - 用 write_only=True 标示只参与反序列化
        sex = serializers.IntegerField(write_only=True)
        # 只有序列化使用 - 自定义字段 - 用 read_only=True 标示只参与序列化
        gender = serializers.SerializerMethodField(read_only=True)
        def get_gender(self, obj):
            return obj.get_sex_display()
        # 序列化与反序列化都不使用 - 1)注释 | 2)required=False, write_only=True
        create_time = serializers.DateTimeField(required=False, write_only=True)
    
        # 为全局校验钩子新增校验字段
        re_password = serializers.CharField(label='确认密码', max_length=64, min_length=3, write_only=True, error_messages={
            'max_length': '确认密码太长',
            'min_length': '确认密码太短'
        })
    
    
        # 反序列化两大方法重写 - 新增create | 更新update
        # 为post接口提供新增Model类对象的功能
        def create(self, validated_data):
            # 返回值:Model类要新增的对象
            return User.objects.create(**validated_data)
    
        # 为put接口提供更新Model类对象的功能
        def update(self, instance, validated_data):
            instance.update(**validated_data)
            # 返回更新后的instance
            return instance
    
    
        # 局部钩子
        def validate_sex(self, value):
            if value not in (0, 1):
                raise serializers.ValidationError('未知性别')
            return value
    
        # 全局钩子
        def validate(self, attrs):
            re_password = attrs.pop('re_password')
            password = attrs.get('password')
            if re_password != password:
                raise serializers.ValidationError('二次密码不一致')
            return attrs
    
    视图类:
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import User
    from .serializers import UserSerializer
    
    # 对应路由:/users/ | /users/pk/
    # 功能:get获取所有 | post新增一个 | put修改一个 | delete删除一个 | get获取一个
    class UsersAPIView(APIView):
        # 获取所有资源 | 单个资源
        def get(self, request, *args, **kwargs):
            # 单个资源的主键
            pk = kwargs.get('pk', None)
            if not pk:
                user_query = User.objects.filter(is_delete=False).all()
            else:
                user_query = User.objects.filter(is_delete=False, pk=pk)
    
            user_data = UserSerializer(instance=user_query, many=True).data
            return Response(
                {
                    'status': 0,
                    'msg': 'ok',
                    'results': user_data
                }
            )
    
        # 新增一个资源
        def post(self, request, *args, **kwargs):
            user_deser = UserSerializer(data=request.data)
    
            # raise_exception值为True,当校验失败,直接返回校验失败的错误信息
            # result = user_deser.is_valid(raise_exception=True)
            result = user_deser.is_valid()
            if result:
                new_user_obj = user_deser.save()
                return Response({
                    'status': 0,
                    'msg': 'success',
                    'result': UserSerializer(new_user_obj).data
                })
            else:
                return Response({
                    'status': 1,
                    'msg': 'failed',
                    'results': user_deser.errors
                })
    
        # 更新一个资源
        def put(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            old_user_query = User.objects.filter(pk=pk, is_delete=False)
            # 没有数据
            if not old_user_query:
                return Response({
                    'status': 1,
                    'msg': 'update failed',
                })
    
            user_deser = UserSerializer(instance=old_user_query, data=request.data)
            result = user_deser.is_valid()
            if result:
                new_user_query = user_deser.save()
                new_user_obj = new_user_query.first()
                return Response({
                    'status': 0,
                    'msg': 'success',
                    'result': UserSerializer(new_user_obj).data
                })
            else:
                return Response({
                    'status': 1,
                    'msg': 'failed',
                    'results': user_deser.errors
                })
    
        # 删除一个资源
        def delete(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            try:
                delete_user_obj = User.objects.get(pk=pk, is_delete=False)
                # 完成删除信息的更新
                delete_user_obj.is_delete = True
                delete_user_obj.save()
                return Response()
            except:
                return Response({
                    'status': 1,
                    'msg': '数据删除失败'
                })
    
  • 相关阅读:
    浅析阿里云API网关的产品架构和常见应用场景
    30分钟全方位了解阿里云Elasticsearch(附公开课完整视频)
    阿里云葛岱斌:让天下没有难做的安全运维
    TPCx-BB官宣最新世界纪录,阿里巴巴计算力持续突破
    从零开始入门 K8s | Kubernetes 网络概念及策略控制
    云栖深度干货 | 打造“云边一体化”,时序时空数据库TSDB技术原理深度解密
    AnalyticDB for PostgreSQL 6.0 新特性介绍
    从零开始入门 K8s | 应用存储和持久化数据卷:核心知识
    K8s 从懵圈到熟练 – 集群网络详解
    理解SqlMapConfig.xml文件
  • 原文地址:https://www.cnblogs.com/huanghongzheng/p/11373700.html
Copyright © 2011-2022 走看看