zoukankan      html  css  js  c++  java
  • day 82 Serializer 基础版系列化类与反系列类

    一级路由:

    from django.contrib import admin
    from api import views
    from django.views.static import serve
    from d_proj import settings
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api1/', include('api1.urls')),
        url(r'^media/(?P<path>.*)', serve, {'document_root':settings.MEDIA_ROOT}),]
    View Code

    二级路由

    from django.conf.urls import url
    from django.contrib import admin
    from api1 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

    views.py

    # 基于django Rest Framework框架drf写restful接口
    #drf使用:
    #1 在setting.py 中把rest_framework加入到app中
    #2 以后再写全写CBV,继承APIView
    
    #为什么要用rest_framework的APIview?
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .api1_serializer import UserSerializer,UserDserializer
    from api1 import models
    
    from rest_framework.request import Request
    from django.http import request
    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:
                # instance = query_list , many=True
                # instance = query_obj, many=False
                userser = UserSerializer(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 = UserDserializer(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'] = UserSerializer(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 = UserDserializer(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'] = UserSerializer(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

    系列化与反系列化

    from rest_framework import serializers
    from . import models
    
    
    class UserSerializer(serializers.Serializer):
        name = serializers.CharField()
        pwd = serializers.CharField()
    
        create_time = serializers.DateTimeField()
    
        gender = serializers.SerializerMethodField() # 可以自定义序列化属性(不需要和Model类属性同步)
        def get_gender(self,obj):  # obj为参与序列化的Model类对象
            # return obj.sex # 0或1
            # 该函数的返回值就作为对应自定义数据序列化后的值
            return obj.get_sex_display()
    
    class UserDserializer(serializers.Serializer):
        name = serializers.CharField(max_length=32,min_length=2, error_messages={
            'max_length':'姓名太长',
            'min_length':'姓名太短',
        })
        pwd = serializers.CharField(max_length=32)
        gender = serializers.IntegerField(source='sex')
    
        # 不校验可以让requires=False
        create_time = serializers.DateTimeField(required=False) # 不是必须的
    
        # 为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)
    
            # query_obj
            for k, v in validated_data.items():
                setattr(instance, k, validated_data.get(k))
            instance.save()
            # instance.name = validated_data.get('name')
            # instance.pwd = validated_data.get('pwd')
            # instance.sex = validated_data.get('sex')
            # instance.save()
            print(instance.name)
            return instance
    View Code

    补充:

    from rest_framework import serializers
    from .api1.api1_serializer import UserSerializer
    from .api1 import models
    from rest_framework.serializers import BaseSerializer
    
    # class UserSerializer(serializers.Serializer):
    #     def get(self, request, *args, **kwargs):
    #         users = models.User.objects.all()
    #         userser = UserSerializer(users, many=True)
    #         self.back_dic['result'] = userser.data
    
    # 找Serializer的初始化类,需要哪些参数
    # serializer没有init,找父类BaseSerializer,三个参数:instance、data、**kwargs
    # 先走父类BaseSerializer中的__new__方法:
     # __new__中如果many=True,走many_init方法, 否则调父类的__new__
    
    
    # instance:系列化参数,接收的是对象如:instance = user_query
    
    # data:反系列参数,接收的是字典如:data = request.data
    # 反系列参数,BaseSerializer类中默认等于empty(空,empty是rest_framework中的一个数据类型),
    # 如果data!=empty,就将data给self.inital_data
    # 如果有data=empty,说明不反系列,将partial[允许局部操作]、ontcext[视图给系列化类传参] pop掉
    
    # kwargs:
    # many 控制了操作多条或者单条
    # __new__中:如果many=True,走many_init方法[最终是走了ListSerializer的listserializer]
    # 否则调父类的__new__,返回了instance【将*args、**kwargs给了instance】
    
    # .data返回一个ReturnDict数据
    
    # 如果没有传递' data= '参数,则:
    # .is_valid()——不可用。
    # # .initial_data -不可用。
    # # .validated_data -不可用。
    # # .错误-不可用。
    # . data -可用。
    
    '''
    class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
        @property
        def data(self):
            ret = super().data
            return ReturnDict(ret, serializer=self)
    
    
    class BaseSerializer(Field):
        def __init__(self, instance=None, data=empty, **kwargs):
            self.instance = instance
            if data is not empty:  # 如果data!=empty,就将data给self.inital_data,
                self.initial_data = data
            self.partial = kwargs.pop('partial', False)
            self._context = kwargs.pop('ontcext', {})
            kwargs.pop('many', None)
            super().__init__(**kwargs)
    
    
        def __new__(cls, *args, *kwargs):
            # We override this method in order to automagically create
            # `ListSerializer` classes instead when `many=True` is set.
            if kwargs.pop('many', False): # 如果many=True,走many_init方法, 否则调父类的__new__
                return cls.many_init(*args, **kwargs)
            return super().__new__(cls, *args, **kwargs)
    '''
    View Code
  • 相关阅读:
    企业应用点点滴滴记入
    jQuery 图片轮播
    javascript setTimeout和setinterval的区别是?
    html5 新增的标签和废除的标签
    H​t​m​l​5​ ​学​习​:​H​T​M​L​5​新​增​结​构​标​签
    WEB前端开发人员须知的常见浏览器兼容问题及解决技巧
    jQuery 简单返回顶部代码
    css 背景色为半透明的例子
    javaScript面试题大全
    Ionic3学习笔记(五)动画之使用 animate.css
  • 原文地址:https://www.cnblogs.com/qingqinxu/p/11372578.html
Copyright © 2011-2022 走看看