• Serializer类进阶二【系列化类、反系列类合并】


    待解决:

      1.系列化字段gender、反系列化字段sex?

      2. 全局钩子,非法信息添加字段?

    一级路由

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app5/', include('app5.urls')),
    ]
    View Code

    二级路由

    from django.conf.urls import url
    from django.contrib import admin
    from app5 import views
    
    urlpatterns = [
        url(r'^users/$', views.Users.as_view()),
        url(r'^users/(?P<pk>d+)/$', views.Users.as_view()),
    ]
    View Code

    models.py

    from django.db import models
    
    class User(models.Model):
        CHOICE_SEX = (
            (0, ''),
            (1, '')
        )
        name = models.CharField(max_length=32, verbose_name="姓名")
        pwd = models.CharField(max_length=32,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 = 'F_user'
            verbose_name_plural = "用户名"
    
        def __str__(self):
            return self.name
    View Code

    serializer.py

    from rest_framework import serializers
    from . import models
    
    # 系列化与反系列化都可以用
    class UserSerializers(serializers.Serializer):
        name = serializers.CharField(max_length=32, min_length=3, error_messages={
            'max_length': '姓名太长',
            'min_length': '姓名太短',
        })
        pwd = serializers.CharField(max_length=32, min_length=3,error_messages={
            'max_length': '密码太长',
            'min_length': '密码太短',})
    
        # 为全局校验钩子新增校验字段
        re_pwd = serializers.CharField(label='确认密码',max_length=32, min_length=3,write_only=True, error_messages={
            'max_length': '确认密码太长',
            'min_length': '确认密码太短', })
    
        # 只参与反系列化
        sex = serializers.IntegerField(write_only=True)
    
        create_time = serializers.DateTimeField(required=False)  # 不是必须的【系列化与反系列化都不使用】
    
        # 只参与系列化 - 自定义字段
        gender = serializers.SerializerMethodField(read_only=True)  # 可以自定义序列化属性(不需要和Model类属性同步)
        def get_gender(self, obj):  # obj为参与序列化的Model类对象
            return obj.get_sex_display()
    
        # 为post接口提供新增Model类对象的功能
        def create(self, validated_data):
            print('create被执行了')
            re = models.User.objects.create(**self.validated_data)
            # 需将创建的对象返回给试图函数,返回给前台
            return re
    
        # 为put提供更新Model类对象的功能
        def update(self, instance, validated_data):
            # 更新query_list
            # instance.update(**validated_data)
            # 将更新后的数据返回前台
            for k, v in validated_data.items():
                setattr(instance, k, validated_data.get(k))
            instance.save()
            return instance
    
        # 局部钩子
        def validate_sex(self, value):
            if value not in (0, 1):
                raise serializers.ValidationError('未知性别')
            return value
    
        # 全局钩子
        def validate(self, attrs):
            re_pwd = attrs.pop('re_pwd')
            pwd = attrs.get('pwd')
            if re_pwd != pwd:
                raise serializers.ValidationError('两次密码不一致')
            return attrs
    View Code

    局部钩子:

    def validate_sex(self, value):
    if value not in (0, 1):
    raise serializers.ValidationError('未知性别')
    return value

    全局钩子:

    def validate(self, attrs):
    re_pwd = attrs.pop('re_pwd')
    pwd = attrs.get('pwd')
    if re_pwd != pwd:
    raise serializers.ValidationError('两次密码不一致')
    return attrs

    views.py

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .serializer import UserSerializers
    from app5 import models
    
    
    # 路由:/users/ | users/pk/
    # 功能:get获取所有| post新增一个 | put修改一个| delete删除一个| get获取一个
    class Users(APIView):
        back_dic = {
            'status':None,
            'msg':'',
            'result':{}
        }
        # 获取所有资源
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk', None)
            if pk:
                # 获取一个
                users_query = models.User.objects.filter(pk=pk, is_delete=False)
            else:
                users_query = models.User.objects.filter(is_delete=False).all()
            if users_query:
    
                userser = UserSerializers(instance=users_query, many=True)
                self.back_dic['result'] = userser.data
                self.back_dic['msg'] = '查询成功'
                self.back_dic['status'] = '0'
            else:
                self.back_dic['msg'] = '查询失败,所查不存在'
                self.back_dic['status'] = '1'
            return Response(self.back_dic)
    
        # 新增一个资源
        def post(self, request, *args, **kwargs):
    
            # models.User.objects.create(**request.data)
            #保存数据前需要对数据进行验证,可以定义一个反系列化类,
            user_deser = UserSerializers(data=request.data)
    
            # 当raise_exception=True 直接将验证不合法信息返回给前台
            # user_deser.is_valid(raise_exception=True)
    
            if user_deser.is_valid():
                # 必须校验通过才可以调用反系列化类中自己写的create方法
                # 可以自己直接调create方法,也可以调save方法,save方法会去调create方法
                # ret = user_deser.create(user_deser.validated_data)
                ret = user_deser.save()
    
                self.back_dic['status'] = 0
                self.back_dic['msg'] = '新增成功'
                self.back_dic['result'] = UserSerializers(instance=ret).data
                return Response(self.back_dic)
            else:
                self.back_dic['status'] = 1
                self.back_dic['msg'] = '新增失败'
                self.back_dic['result'] = user_deser.errors
                return Response(self.back_dic)
    
        # 更新一个,需要自定义update方法
        def put(self, request, *args, **kwargs):
            # 修改的对象【query_list】
            # update_query = models.User.objects.filter(pk=kwargs.get('pk', None))
            # user_ser = UserDserializer(instance=update_query, data=request.data)
    
            # 修改的对象【query_obj】
            update_query_obj = models.User.objects.filter(pk=kwargs.get('pk', None)).first()
            user_ser = UserSerializers(instance=update_query_obj, data=request.data)
    
            if user_ser.is_valid():
                # ret_query = user_ser.update(instance=update_query,validated_data=user_ser.validated_data)
                # 可以自己直接调update方法,也可以调save方法,save方法会去调create方法
                ret_query = user_ser.save()
                self.back_dic['status'] = 0
                self.back_dic['msg'] = '更新成功'
                # 【query_list】
                # self.back_dic['result'] = UserSerializer(instance=ret_query, many=True).data
    
                #[query_obj]
                self.back_dic['result'] = UserSerializers(instance=ret_query,many=False).data
            else:
                self.back_dic['status'] = 1
                self.back_dic['msg'] = '更新失败'
                self.back_dic['result'] = user_ser.errors
            return Response(self.back_dic)
    
        def delete(self, request, *args, **kwargs):
            models.User.objects.filter(pk=kwargs.get('pk'), is_delete=False).update(is_delete=True)
    
            return  Response('delete ok')
    View Code
  • 相关阅读:
    cocospods 卡在 Analyzing dependencies
    android px、sp、dp之间的互转
    Android 4.4环境搭建——Android SDK下载与安装
    我心中的核心组件(可插拔的AOP)~大话开篇及目录
    EF架构~AutoMapper对象映射工具简化了实体赋值的过程
    我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器
    EF架构~为EF DbContext生成的实体添加注释(T5模板应用)
    品味编程~底层开发人员应该这样设计一个字体类
    Study notes for Clustering and K-means
    深入理解Oracle索引(25):一招鲜、吃遍天之单字段索引创建思路
  • 原文地址:https://www.cnblogs.com/qingqinxu/p/11373342.html
Copyright © 2020-2023  润新知