REST framework(序列化器)
一、字段参数
字段的常见参数: required=True 字段不能为空 allow_null=True 字段允许为null allow_blank=True 数据校验阶段,字段可以为null write_only=True 字段只能写 read_only=True 字段只能读 source="related_name" # 指定别名 default="默认值" 指定字段默认值 format="%Y-%m-%d %X" 设置时间格式 error_messages={"max_length":"字段太长"} 指定错误信息
二、序列化器Serializer类
注:source 可以指定一个字段名,表模型,还可以指定表模型里的方法,source 指定的如果是方法不用加括号自己执行
序列化器Serializer类:
1,写一个类继承serializers.Serializer 2,视图层调这个类实例化产生实例化对象 3,注意返回用的是rest_framework 的 Response from rest_framework import serializers class BookSerialize(serializers.Serializer): nid = serializers.CharField() # (1)source的用法1:起别名 # name = serializers.CharField(source="name") # source 指定要序列化的字段,不能写两个name author_name = serializers.CharField(source="name") # 相当于给name字段显示起别名为book_name price = serializers.CharField() # (2)source的用法2:可以指定表模型 # publish = serializers.CharField() # 可以利用__str__ 显示序列化 # publish = serializers.CharField(source="publish.name") # source可以指定表模型 # (3)source的用法3:指定表模型的方法,相当于直接触发序列化表里的方法执行 # xx = serializers.CharField(source="test") # source可以指定表模型的方法,将该返回值的结果赋值给xx 相当于给表模型添加字段 # rest_framework组件之SerializerMethodField 的方法使用,写一个get+字段名的函数 authors = serializers.SerializerMethodField() def get_authors(self, obj): # obj为序列化的对象 author_list = obj.authors.all() ser = AuthorSerialize(author_list, many=True) return ser.data # 返回的结果为序列化打印的对象
视图:
视图层: from rest_framework.views import APIView from rest_framework.response import Response from app01.myserialize import BookSerialize class Books(APIView): def get(self, request, *args, **kwargs): response = {"status": 100, "msg": "查看所有"} # 方式1:自己手撸序列化 book_list = models.Book.objects.all() data = [{"title": book.title, "publish_date": book.publishDate} for book in book_list ] return HttpResponse("ok") # 方式2:django原生自带序列化 (不推荐使用) from django.cores.serializes import serialize books = models.Book.objects.all() data = serialize(books,'json') # django自带的序列化组件 return HttpResponse(data) # 方式3:推荐使用 all_author = Author.objects.all() # 产生序列化的对象 ser = BookSerialize(all_author, many=True) # many=True 表示序列化多条 many=False 表示序列化单条 response["data"] = ser.data # 序列化以后的数据在data里 return Response(response) # 方式4: ret=models.Book.objects.all().values('nid','title') dd=list(ret) return HttpResponse(json.dumps(dd))
三、序列化器ModelSerializer类
3.1 单层的序列化器:
序列化器ModelSerializer类:
1,写一个类继承ModelSerializer 2,视图层调这个类实例化产生实例化对象 3,注意返回用的是rest_framework 的 Response from rest_framework import serializers class BookSerialize(serializers.ModelSerializer): # ModelSerializer类下接元信息 class Meta: model = models.Author # fields = ["name",] # 指定序列化哪些字段 fields = '__all__' # 序列化所有字段 一般不用 # exclude = ["name", ] # 排除那些字段不显示,不与查询所有连用 # depth=1 指定查询的深度 publish=serializers.CharField(source='publish.name') # 元信息连表显示的是字段id 所以重写序列化字段
视图:
视图层: from rest_framework.views import APIView from rest_framework.response import Response from app01.myserialize import BookSerialize class Books(APIView): def get(self, request, *args, **kwargs): response = {"status": 100, "msg": "查看所有"} all_author = Author.objects.all() # 产生序列化的对象 ser = BookSerialize(all_author, many=True) # many=True 表示序列化多条 response["data"] = ser.data # 序列化以后的数据在data里 return Response(response)
3.2 层级序列化器:
调查表-->模板表-->问卷调查表-->问题选项表
# 问题选项 class SurveyChoiceSerializer(serializers.ModelSerializer): class Meta: model = models.SurveyChoice fields = "__all__" # 问卷调查问题表 class SurveyQuestionSerializer(serializers.ModelSerializer): # 层级序列化器方式三: # choices = serializers.SerializerMethodField() # 创建需要查询的字段函数:get+字段名 # def get_choices(self, obj): # # 反向查询:表名(小写)_set # return list(obj.surveychoice_set.values()) # 基于对象的查找 """" 层级序列化器方式三总结: 1.正向查询:当前表的字段名.需要查询的关联表的字段名 2.反向查询:关联表(小写)_set.values() """ """ 层级序列化器方式一总结: 1.many参数:只有manytomany字段需要指定many=True 2.source参数: 正向查询:source="字段.关联表字段",当前字段可以取别名 反向查询:models表中添加related_name参数:当前使用的子序列化器指定source=related_name(值) 多条记录:source=字段.all """ # 问卷问题选项 choices = SurveyChoiceSerializer(many=True, source="answers") # 自定义value字段 value = serializers.CharField(default="", error_messages={ "invalid": "无效的类型", "blank": "不可为空", "min_length": "最少15个字" }) # 自定义错误字段 # 创建自定义独立字段question # required=True 字段不能为空 # allow_null=True 字段允许为null # allow_blank=True 数据校验阶段,字段可以为null # write_only=True 字段只能写 # read_only=True 字段只能读 error = serializers.CharField(default="", required=False, allow_blank=True, allow_null=True) class Meta: model = models.SurveyQuestion fields = ( "question", "id", "survey_type", "title", "choices", "value", "error" ) # 定义全局钩子 def validate(self, attrs): if attrs.get("survey_type") != "choice": if len(attrs["value"]) <= 15: raise serializers.ValidationError("填写内容不能少于15个字") return attrs # 自定制返回内容 # 重写方法 def to_internal_value(self, data): data["question"] = self.Meta.model.objects.get(pk=data["id"]) return data # 模板序列化器 class SurveyTemplateSerializer(serializers.ModelSerializer): # 层级序列化器方式二:通过直接指定类名(manytomany字段需要参数:many=True,foreignkey字段则不需要) questions = SurveyQuestionSerializer(many=True) class Meta: model = models.SurveyTemplate fields = ( "id", "name", "questions", ) # 调查表序列化器 class SurveyDetailSerializer(serializers.ModelSerializer): # 层级序列化器方式一:通过ListSerializer指定(child=指定需要关联子序列化类) # read_only 只允许读 # 只有manytomany字段需要指定many=True,其他foreignkey字段或者onetoone字段不需要指定many参数 survey_templates = serializers.ListSerializer(child=SurveyTemplateSerializer(), read_only=True) class Meta: model = models.Survey fields = ( "id", "survey_templates" )
四、序列化器的数据校验(局部钩子与全局钩子函数)
4.1 定义钩子函数进行数据校验:
注:rest_framework 钩子函数源码 从 is_valid 入口
语法: validate + 校验字段名 from rest_framework.exceptions import ValidationError class BookSerialize(serializers.ModelSerializer): class Meta: model = models.Author fields = '__all__' # 序列化所有字段 一般不用 # 局部钩子 写在序列化组件里 def validate_name(self,value): if value.startswith("sb"): raise ValidationError("不能以sb开头") return value # 全局钩子 所有字段校验通过 def validate(self, value): name = value.get("name") price = value.get("price") if name != price: raise ValidationError("书与价格不能比较") return value
4.2 通过重写父类方法进行数据校验:
注意:当前视图函数继承CreateAPIView类
from rest_framework.exceptions import ValidationError class BookSerialize(serializers.ModelSerializer): class Meta: model = models.Author fields = '__all__' # 序列化所有字段 一般不用 # 创建新数据 # 重写CreateAPIView中的create方法 def create(self, validated_data): validated_data.pop("price", None) # 删除当前无用字段 return super(SurveyCreateSerializer, self).create(validated_data)
五、序列化器自定义字段
class SurveyQuestionSerializer(serializers.ModelSerializer): # 自定义字段方式一 error = serializers.CharField(default="", required=False, allow_blank=True, allow_null=True) # 自定义字段方式二
# 重写父类方法
def to_representation(self, instance): data = super(SurveyQuestionSerializer, self).to_representation(instance) data["name"] = "xxx" # 自定义字段 return data class Meta: model = models.SurveyQuestion fields = ( "error", "id", "title", "name" )
https://www.cnblogs.com/WiseAdministrator/