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
原文地址:https://www.cnblogs.com/qingqinxu/p/11372578.html