zoukankan      html  css  js  c++  java
  • Django Rest framework序列化流程

    目录

    一 什么是序列化
    二 Django REST framework配置流程之Serializer
    三 Django REST framework配置流程之ModelSerializer

    一 什么是序列化

    序列化模型与序列化关系模型
    序列化模型,顾名思义,即对 models 里的数据模型作序列化。
    而序列化关系模型则是对 models 里数据模型中带有关系的如 ForeignKey, ManyToManyField 和 OneToOneField 字段作序列化。
    Django Rest Framework 提供了灵活的序列化关系模型,让开发者可以自由定制序列化数据模型。

    二 Django REST framework配置流程之Serializer

    1、GET请求

    1. 写一个序列化的类,这个类需要继承Serializer,一对多字段可以直接通过指定source字段来查找。如果是多对多的字段则需要做进一步处理才能在页面显示
    from rest_framework import serializers
    class UserInfoSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=32)
        pwd = serializers.CharField(max_length=128)
        # 多对多跨表查询,查询到的是所有对象
        been_city = serializers.CharField(source="been_city.all")
    
    1. 视图函数的配置
    class IndexView(APIView):
    
        def get(self, request):
            user_list = models.UserInfo.objects.all()
            # 获取到的是一个serializer对象,如果user_list是一个对象则不需要many=True
            ser = UserInfoSe rializer(instance=user_list, many=True)
            # print(ser)
            """
            UserInfoSerializer(instance=<QuerySet []>, many=True):
            name = CharField(max_length=32)
            pwd = CharField(max_length=128)
            been_city = CharField(source='city.name')
            """
            # ser.data是一个有序字典
            return Response(ser.data)
    
    1. 启动项目访问url,可以看到多对多字段只能显示object

    2. 处理多对多字段的显示
      a) 方法一:重写CharField的to_representation方法,这个方法就是用来显示最终数据的

    class MyCharField(serializers.CharField):
        def to_representation(self, value):
            # value就是QuerySet对象列表
            data_list = []
            for row in value:
                data_list.append({'name': row.name, 'province': row.province.name})
            return data_list
    
    
    class UserInfoSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=32)
        pwd = serializers.CharField(max_length=128)
        # 通过自定义的MyCharField中的to_representation处理多对多字段的QuerySet对象
        been_city = MyCharField(source="been_city.all")
    

     b) 方法二:通过ListField方法

    class MyCharField(serializers.CharField):
        def to_representation(self, value):
            # value就是每个QuerySet对象
    
            return {‘id’:value.pk, "name": value.name, "province":value.province.name}
    
    
    class UserInfoSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=32)
        pwd = serializers.CharField(max_length=128)
        # 通过自定义的MyCharField中的to_representation处理多对多字段的QuerySet对象
        been_city = serializers.ListField(child=MyCharField(),source="been_city.all")
    

     c) 方法三:通过定义serializers.SerializerMethodField()可以生成对象列表,然后通过get方法,可以接收对象,并返回需要的json数据

    class UserInfoSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=32)
        pwd = serializers.CharField(max_length=128)
        # 多对多跨表查询,查询到的是所有city对象
        # been_city = serializers.CharField(source="been_city.all")
        # print(been_city)
        # provinse = serializers.CharField(source="been_city.province")
        been_city = serializers.SerializerMethodField()  # 获取到的是UserInfo对象
    
        def get_been_city(self, obj):
            print(obj)
            city_list = obj.been_city.all()
            data_list = []
            for row in city_list:
                data_list.append({'name': row.name, 'province': row.province.name})
            return data_list
    

    源码浏览

    访问URL效果

    2、POST请求

    1. 数据验证配置
    class PasswordValidator(object):
        def __init__(self, base):
            self.base = base
        def __call__(self, value):
            if value != self.base:
                message = '用户输入的值必须是 %s.' % self.base
                raise serializers.ValidationError(message)
    class UserInfoSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=32)
        pwd = serializers.CharField(max_length=128, error_messages={'required': '密码不能为空'},
                                    validators=[PasswordValidator('666'), ]
    
    1. 在视图函数里面写post方法,并且根据用户发送的数据做序列化操作
    class IndexView(APIView):
        def post(self, request):
            # 接收POST数据
            data = request.POST
            # 序列化数据,基于Serializer和ModelSerializer都可以
            # ser = UserInfoSerializer(data=data, many=True)
            ser = UserInfoModelSerializer(data=data, many=True)
            # 判断数据是否符合要求
            if ser.is_valid():
                print(ser.validated_data)  # OrderedDict([('name', 'jack'), ('pwd', '123')])
                # models.UserInfo.objects.create(**ser.validated_data)
                return Response('添加成功')
            return Response("POST测试")
    

    三 Django REST framework配置流程之ModelSerializer

    1、基础配置实例

    class UserInfoSerializer(serializers.ModelSerializer):
        class Meta:
            # model表
            model = models.UserInfo
            fields = '__all__'
            # fields = []  # 可以指定字段
            # 遍历的深度
            depth = 2
    

    2、自定义简单字段实例配置

    class UserInfoSerializer(serializers.ModelSerializer):
        # 可以通过serializers自定义字段
        xxx = serializers.CharField(source="name")
        class Meta:
            # model表
            model = models.UserInfo
            fields = '__all__'
            # fields = []  # 可以指定字段
            # 遍历的深度
            depth = 2
    

    3、基于HyperlinkedRelatedField实现url的实例配置

    class UserInfoSerializer(serializers.ModelSerializer):
        #view_name是用来反向生成url的
        xxx = serializers.HyperlinkedRelatedField(view_name="detail")
        class Meta:
            # model表
            model = models.UserInfo
            fields = '__all__'
            # fields = []  # 可以指定字段
            # 遍历的深度
            depth = 2
    
    # urls.py配置
    urlpatterns = [
        # 由于在class HyperlinkedRelatedField(RelatedField)中定义了lookup_field="pk",
        # 所以在url中必须使用pk字段
        url(r'xxx/(?P<pk>d+)', views.UserView.as_view(), name='detail'),
    ]
    
    # UserView配置
    class UserView(APIView):
        def get(self, request):
            user_list = models.UserInfo.objects.all()
            ser = UserSerializer(instance=user_list, many=True, content={"request":request})
            return Response(ser.data)
    

    4、全部生成url(serializers.HyperlinkedModelSerializer会把每个字段都成条url,默认的view_name是userinfo-detail

    class ModelUserSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = '__all__'  # 生成url
            # fields = ['name', 'pwd']  # 只显示字段
            # exclude = ['role',]
    
    # urls.py配置
    urlpatterns = [
        url(r'^xxx/(?P<pk>d+)', view.UserView.as_view(), name='userinfo-detail'),
        url(r'^xxx/(?P<pk>d+)', view.UserView.as_view(), name='group-detail'),
        url(r'^xxx/(?P<pk>d+)', view.UserView.as_view(), name='role-detail'),
    ]
    
  • 相关阅读:
    Assimp对FBX文件中geometric transformations的处理
    VSM
    WSL安装
    [p1880][NOI1995]石子合并
    【日常】集训总结
    【模板】背包
    【济南集训】20191006解题报告
    [P1516]青蛙的约会
    【模板】ST表
    【济南集训】20191001解题报告
  • 原文地址:https://www.cnblogs.com/eric_yi/p/8432315.html
Copyright © 2011-2022 走看看