Django REST Framework学习(2)

序列化器的使用

一对多查询

方式1 获取多表中关联的主键id

serializer

# 自定义序列化器
class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
    bread = serializers.IntegerField(max_value=100, min_value=5)
    bpub_date = serializers.DateField()
    bcomment = serializers.IntegerField(default=10)

    # 返回多表中关联的英雄id   PrimaryKeyRelatedField
    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)

结果展示

[
    {
        "bread": 89,
        "bpub_date": "2021-07-03",
        "bcomment": 110,
        "heroinfo_set": [
            1,
            2,
            3,
            4
        ]
    },
    {
        "bread": 99,
        "bpub_date": "2021-07-01",
        "bcomment": 11,
        "heroinfo_set": [
            5,
            6
        ]
    },
    {
        "bread": 79,
        "bpub_date": "2021-05-01",
        "bcomment": 81,
        "heroinfo_set": [
            7
        ]
    }
]

方式2 获取多表中关联的str方法值

serializer

# 自定义序列化器
class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
    bread = serializers.IntegerField(max_value=100, min_value=5)
    bpub_date = serializers.DateField()
    bcomment = serializers.IntegerField(default=10)

    # 返回关联的英雄id   PrimaryKeyRelatedField
    # heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    # 返回多表中关联英雄模型类的str方法值
    heroinfo_set = serializers.StringRelatedField(read_only=True, many=True)

结果展示

[
    {
        "bread": 89,
        "bpub_date": "2021-07-03",
        "bcomment": 110,
        "heroinfo_set": [
            "曹操",
            "周瑜",
            "刘备",
            "貂蝉"
        ]
    },
    {
        "bread": 99,
        "bpub_date": "2021-07-01",
        "bcomment": 11,
        "heroinfo_set": [
            "孙悟空",
            "白骨精"
        ]
    },
    {
        "bread": 79,
        "bpub_date": "2021-05-01",
        "bcomment": 81,
        "heroinfo_set": [
            "潘金莲"
        ]
    }
]

方式3 自定义多表的序列化器可以获得想要的多表中的字段

serializer
新建多表的序列化器

class HeroInfoSerialzier(serializers.Serializer):
    # 英雄序列化器
    hname = serializers.CharField()
    hcomment = serializers.CharField()

class BookSerialzier(serializers.Serializer):
    # 图书序列化器
    btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
    bread = serializers.IntegerField(max_value=100, min_value=5)
    bpub_date = serializers.DateField()
    bcomment = serializers.IntegerField(default=10)

    heroinfo_set = HeroInfoSerialzier(many=True)
注意:HeroInfoSerialzier必须先于BookSerialzier,否则报错

结果展示

[
    {
        "bread": 89,
        "bpub_date": "2021-07-03",
        "bcomment": 110,
        "heroinfo_set": [
            {
                "hname": "曹操",
                "hcomment": null
            },
            {
                "hname": "周瑜",
                "hcomment": null
            },
            {
                "hname": "刘备",
                "hcomment": null
            },
            {
                "hname": "貂蝉",
                "hcomment": null
            }
        ]
    },
    {
        "bread": 99,
        "bpub_date": "2021-07-01",
        "bcomment": 11,
        "heroinfo_set": [
            {
                "hname": "孙悟空",
                "hcomment": null
            },
            {
                "hname": "白骨精",
                "hcomment": null
            }
        ]
    },
    {
        "bread": 79,
        "bpub_date": "2021-05-01",
        "bcomment": 81,
        "heroinfo_set": [
            {
                "hname": "潘金莲",
                "hcomment": null
            }
        ]
    }
]

选项参数方法验证

serialzier
如字段max_length=20最大长度20, min_length=5最小长度5,write_only=True只参与反序列化,read_onle=True只参与序列化,required=True必传,default=10默认值为10,unique=True唯一值

class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
    bread = serializers.IntegerField(max_value=100, min_value=5)
    bpub_date = serializers.DateField()
    bcomment = serializers.IntegerField(default=10)

view
需要调用is_valid()方法来验证字段

class BookDRFView(View):
    """
        单一更新和删除
    """
    def put(self, request, pk):
        # 1、获取前端数据
        data = request.body.decode()
        data_dict = json.loads(data)
        # 2、验证数据
        try:
            book = BookInfo.objects.get(id=pk)
        except:
            return JsonResponse({'error': '错误信息'}, status=400)
        ser=BookSerialzier(book,data=data_dict)
        ser.is_valid()
        # 3、更新数据
        ser.save()
        # 4、返回结果
        return JsonResponse(ser.data)

自定义方法验证

class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
    bread = serializers.IntegerField(max_value=100, min_value=5)
    bpub_date = serializers.DateField()
    bcomment = serializers.IntegerField(default=10)

    # 返回关联的英雄id   PrimaryKeyRelatedField
    # heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    # 返回关联英雄模型类的str方法值
    # heroinfo_set = serializers.StringRelatedField(read_only=True, many=True)
    heroinfo_set = HeroInfoSerialzier(many=True)
	# 单一字段验证
	# validate_字段名   格式固定死了,不然无效
    def validate_btitle(self, value):

        if value == '黄色':
            raise serializers.ValidationError('书名不能是黄色')
        return value

    # 多个字段验证
    def validate(self, attrs):

        if attrs['bread'] < attrs['bcomment']:
            raise serializers.ValidationError('阅读量大于评论量')

        return attrs

view中获取验证后的数据validated_data

    def post(self, request):
        # 1、获取前端数据
        data = request.body.decode()
        data_dict = json.loads(data)
        # 2、验证数据
        ser = BookSerialzier(data=data_dict)
        ser.is_valid()  # 验证方法
        print(ser.validated_data)  # 获取验证后的字段数据
        # 3、保存数据
        ser.save()
        # 4、返回结果
        return JsonResponse(ser.data)

保存数据

view中save()保存数据

	def post(self, request):
        # 1、获取前端数据
        data = request.body.decode()
        data_dict = json.loads(data)
        # 2、验证数据
        ser = BookSerialzier(data=data_dict)
        ser.is_valid()  # 验证方法
        print(ser.validated_data)  # 获取验证后的字段数据
        # 3、保存数据
        ser.save()
        # 4、返回结果
        return JsonResponse(ser.data)

Serialzier中create拆包保存

    def create(self, validated_data):
        # 保存数据
        book = BookInfo.objects.create(**validated_data)

        return book

更新

view 注意BookSerialzier参数

    def put(self, request, pk):
        # 1、获取前端数据
        data = request.body.decode()
        data_dict = json.loads(data)
        # 2、验证数据
        try:
            book = BookInfo.objects.get(id=pk)
        except:
            return JsonResponse({'error': '错误信息'}, status=400)
        ser=BookSerialzier(book,data=data_dict)
        ser.is_valid()
        # 3、更新数据
        ser.save()
        # 4、返回结果
        return JsonResponse(ser.data)

Serialzier

    def update(self, instance, validated_data):
        # 更新数据
        instance.btitle = validated_data['btitle']
        instance.bread = validated_data['bread']
        instance.save()
        return instance

ModelSerializer

class BookModelSerialzier(serializers.ModelSerializer):
    # 显示指明字段
    bread=serializers.IntegerField(max_value=100,min_value=20)
    sms_code=serializers.CharField(max_length=6,min_length=6)
    class Meta:
        model=BookInfo # 指定生成字段的模型类
        fields=('btitle','bread','sms_code') # 指定模型类中的字段
        # fields='__all__' # 指定模型类中的字段
        read_only_fields=('btitle',)
        # exclude=('btitle',)  # 排除模型类中的字段
        # 添加修改字段选项参数
        # extra_kwargs={
        #     "bcomment":{
        #         'max_value':100
        #     },
        #     'btitle':{
        #         'min_length':5
        #     }
        #
        # }


    # def validate(self, attrs):
    #
    #
    # def validate_btitle(self, data):
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值