序列化与反序列化
序列化和反序列化的定义及作用:
序列化 是将程序语言转换为JSON/XML;反序列化 是将JSON/XML转换为程序语言;
对应到Django中,序列化即把模型对象转换为字典形式, 在返回给前端,主要用于输出, 反序列化是将接受前端的字典类型数据,通过验证再转换为模型对象.
序列化器的作用:
进行数据的校验 对数据对象进行转换
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__'
字段与选项
字段 字段构造方式 BooleanField BooleanField() NullBooleanField NullBooleanField() CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) UUIDField UUIDField(format=‘hex_verbose’) IPAddressField IPAddressField(protocol=‘both’, unpack_ipv4=False, **options) IntegerField IntegerField(max_value=None, min_value=None) FloatField FloatField(max_value=None, min_value=None) DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None) FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) ImageField ImageField(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页面时,显示的字段帮助提示信息
最佳实践
案例一:多级外键如何处理
表结构
序列化器代码:
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()