Django中序列化器的使用技巧

序列化与反序列化

序列化和反序列化的定义及作用:

  • 序列化是将程序语言转换为JSON/XML;反序列化是将JSON/XML转换为程序语言;

  • 对应到Django中,序列化即把模型对象转换为字典形式, 在返回给前端,主要用于输出, 反序列化是将接受前端的字典类型数据,通过验证再转换为模型对象.

序列化器的作用:

  1. 进行数据的校验
  2. 对数据对象进行转换

DRF中的序列化器

定义方法

    class BookInfoSerializer(serializers.Serializer):
        """图书数据序列化器"""
        id = serializers.IntegerField(label='ID', read_only=True)
        btitle = serializers.CharField(label='名称', max_length=20)
        bpub_date = serializers.DateField(label='发布日期', required=False)
        bread = serializers.IntegerField(label='阅读量', required=False)
        bcomment = serializers.IntegerField(label='评论量', required=False)
        image = serializers.ImageField(label='图片', required=False)
        
        class Meta:
            model = BookInfo
            fields ='__all__'

字段与选项

字段字段构造方式
BooleanFieldBooleanField()
NullBooleanFieldNullBooleanField()
CharFieldCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
UUIDFieldUUIDField(format=‘hex_verbose’)
IPAddressFieldIPAddressField(protocol=‘both’, unpack_ipv4=False, **options)
IntegerFieldIntegerField(max_value=None, min_value=None)
FloatFieldFloatField(max_value=None, min_value=None)
DecimalFieldDecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)
DateTimeFieldDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
DateFieldDateField(format=api_settings.DATE_FORMAT, input_formats=None)
FileFieldFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
ImageFieldImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
  • 选项参数
参数名称作用
max_length最大长度
min_length最小长度
allow_blank是否允许为空
trim_whitespace是否截断空白字符
max_value最小值
min_value最大值
  • 通用参数
参数名称说明
read_only表明该字段仅用于序列化输出,默认False
write_only表明该字段仅用于反序列化输入,默认False
required表明该字段在反序列化时必须输入,默认True
default反序列化时使用的默认值
allow_null表明该字段是否允许传入None,默认False
validators该字段使用的验证器
error_messages包含错误编号与错误信息的字典
label用于HTML展示API页面时,显示的字段名称
help_text用于HTML展示API页面时,显示的字段帮助提示信息

最佳实践

案例一:多级外键如何处理

表结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5sZ3PtD3-1594563893123)(DC7CA2DF97B341258E3F6D064437BA04)]

序列化器代码:
    class AssetSerializer(serializers.ModelSerializer):
        
        
        location_detail__name = serializer.CharField(source='location_detail.name',read_only=True)
        location_detail_-room__name = serializer.CharField(source='location_detail.room.name',read_only=True)
        location_detail__room__building__name = serializer.CharField(source='location_detail.room.building.name',read_only=True)
        location_detail__room__building__region__name = serializer.CharField(source='location_detail.room.buidling.region.name',read_only=True)
        
        class Meta:
            model = Asset
            fields = '__all__'
总结
  • 双下划线代表关联外键,如果有多层外键,可以一直通过此种方式关联,最终形成的SQL语句为多表left join形式。

案例二:choices字段如何处理。

表结构
    class DeviceOnService(models.Model):
        on_service_type_choices = (
            ('0','普通设备上线'),
            ('1','普通设备上线'),
            ('2','普通设备上线'),
        )
        
        on_service_type = models.CharField(choices=on_service_type_choices,max_length=100,verbose_name='在线类型')
        update_time = models.DatetimeField(null=True,blacnk=True,verbose_name='购买时间')
        
        
序列化器代码
    class DeviceOnServiceSerializer(serializer.ModelSerializer):
        on_service_type__display_name = serializers.ChoiceField(choices=DeviceOnService.on_service_type_choices,source='get_on_service_type_display',read_only=True)
        # 时间类型,传给前端时,也需要特殊处理,规定显示格式。
        update_time = serializers.DatetimeField(format('%Y-%m-%d %H:%M:%S'),required=False,allow_null=True)
        

总结
  • choices字段的处理方法类似于外键,添加显示字段。
  • 时间类型,传给前端时,需要规定显示格式。

案例三:序列化方法

表结构
    class Role(models.Model):
        name = models.CharField(max_length=128,verbose_name='角色',default='guest')
        info = models.CharField(max_length=128,verbose_name='说明',default='请输入角色说明')
        
    class Meta:
        verbose_name = '角色'
        verbose_name_plural = verbose_name
序列化器代码
    class RoleDisplaySerializer(serializers.ModelSerializer):
        key = serializers.IntergerField(source='id',read_only=True)
        label = serializers.SerializerMethodField()
        
        class Meta:
            model = Role
            fields = ('key','label')
        
        def get_label(self, obj):
            return '{}({})'.format(obj.name,obj.info)
总结
  • 序列化中需要把一个方法作为属性输出时,方法命名要求:get_field(),序列化字段:field = serializers.SerializerMethodField()
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值