1,序列化
- 声明序列化器,具体代码如下
from rest_framework import serializers from DrfDemo.models import Book # -----------------------这是第一版get请求的serializers------------------ class PublisherSerializrs(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) # 在类中写了字段,书写校验这个字段 class AuthorSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32) class BookSerializer(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) pub_time = serializers.DateField() category = serializers.CharField(source="get_category_display") # 关于外键的验证用外键字段名Serializers的方法 publisher = PublisherSerializrs() authors = AuthorSerializer(many=True)
- 业务逻辑处理部分
2,反序列化,post请求
- 确定新增的数据结构
- 序列化器
- 正序和反序字段不统一
- required= False 只序列化,不走校验
- read_only=True 只序列化用
- write_only =True 只反序列化用
- 重写create方法
- 验证通过返回ser_obj.validated_data
- 验证不通过返回ser_obj.errors
3,反序列化,put/patch请求
- 重写update方法
- ser_obj = Bookserializer(instance=obj, data=request.data, partial=True)
- 验证通过返回ser_obj.validated_data
- 验证不通过返回ser_obj.errors
4,验证
- 自定义的验证 权重111
-
- def_my_validate(value):
- 不通过抛异常:raise serializer.ValidationError("错误信息")
- 通过return value
- 配置----->给字段加validations=[My_validate]
- def_my_validate(value):
- 单个字段的验证 权重222
-
- def validate_字段名称(self, value):
- 不通过raise serializers.ValidationErrors("错误信息")
- def validate_字段名称(self, value):
- 多个字段的验证 权重333
-
- def validate(self, attrs):
- attrs是所有字段组成的字典
- 不通过raise serializers.ValidationError("错误信息")
- def validate(self, attrs):
from rest_framework.views import APIView from rest_framework.response import Response from DrfDemo.models import Book from DrfDemo.serializers import BookSerializer class BookView(APIView): # 定义一个get请求的额度方法 def get(self, request): # 从数据库中获取数据 book_queryset = Book.objects.all() print() # 用序列化器进行序列化 ser_obj = BookSerializer(book_queryset, many=True) # 既然用rest_frame框架就用人家提供的response return Response(ser_obj.data) # 手写一个post获取数据的方法(新增) def post(self, request): # 1,确定数据类型以及数据结构 # 2,对前端妹子传过来的的数据进行校验 book_obj = request.data # 获取前端传过来的数据 print("前端传过来的数据:", book_obj, type(book_obj)) # 把获取到的数传给BookSerializer方法里进行校验 ser_obj = BookSerializer(data=book_obj) # 如果通过校验 if ser_obj.is_valid(): print("通过校验的数据:", ser_obj) # 把通过校验的更新到数据库中 ser_obj.save() print(456) # 更新完以后把更新后的数据展示到前端 return Response(ser_obj.validated_data) # 如果没通过校验就返回错误信息,错误信息都封装在了ser_obj中 return Response(ser_obj.errors) # 编辑CBV class BookEditView(APIView): # 手写一个get请求 def get(self, request, id): # 获取到要更新数据的对象 book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(book_obj) # 单个对象的时候不用many=True # 返回这个数据经过序列化的数据 return Response(ser_obj.data) # 手写一个put更新的方法 def put(self, request, id): book_obj = Book.objects.filter(id=id).first() # 把筛选到的对象去调用BookSerializer方法 ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) print(ser_obj) if ser_obj.is_valid(): ser_obj.save() print(123) # 返回经过更新到数据库的数据 return Response(ser_obj.validated_data) # 否则报错误 return Response(ser_obj.errors) 序列化代码
5,序列化器的ModelSerializer
- 定义一个序列化器继承(serializers.ModelSerializer)
- 源信息的配置
- class Meta
- fileds = "__all__"
- exclude = ["字段名",]
- depth = 1 (depth会让所有的外键关系字段都变成read_only = True)
- extra_kwargs= {"默认的字段名称":{自定义的参数配置信息}}
- SerializerMethodField()方法字段
- def get_字段名称(self, obj):
- obj 每次序列化的模型对象
- return 自定义的数据
- def get_字段名称(self, obj):
def my_validate(value): print(value) if "雪雪" in value.lower(): raise serializers.ValidationError("这太暴露了") return value class PublisherSerializrs(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) # 在类中写了字段,书写校验这个字段 class AuthorSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(max_length=32) # 重新写Book的序列化器 class BookSerializer(serializers.Serializer): # 1,不是进行必须的序列化和反序列化 id = serializers.IntegerField(required=False) # 表示不是必须进行序列化 # 2,默认的字段,不管是序列化,还是反序列化都需要通过这几个字段 title = serializers.CharField(max_length=32, validators=[my_validate]) pub_time = serializers.DateField() # 3,序列化要走的字段 category = serializers.CharField(source="get_category_display", read_only=True) publisher = PublisherSerializrs(read_only=True) authors = AuthorSerializer(many=True, read_only=True) # 多对多要用many=True # 4,反序列化要走的字段 # 反序列化提交的数据都是自定义的不是字段名(注意自定的数据这的字段名和提交数据一致,否则报错) post_category = serializers.IntegerField(write_only=True) publisher_id = serializers.IntegerField(write_only=True) author_list = serializers.ListField(write_only=True) # 1,提交数据的时候要重写create方法(增加的时候) def create(self, validated_data): # validated_data 校验通过的数据就是book_obj,通过ORM操作给Boook表增加数据 print("在view中通过校验的数据:",validated_data) book_obj = Book.objects.create( title=validated_data["title"], pub_time=validated_data["pub_time"], category=validated_data["post_category"], publisher_id=validated_data["publisher_id"] ) print("serializers中的book_obj", book_obj) # 需要把这个对象的多对多的数据创建出来 book_obj.authors.add(*validated_data["author_list"]) # 把值存在于ORM的操作更新到数据库中 # book_obj.save() print(123) return book_obj # 2,更新数据的方法 def update(self, instance, validated_data): # 参数说明:instance是要更新的book_obj对象, validated_data是通过校验的数据 # 接下来就是ORM操作, 把要所有哦的字段都要写一遍 instance.title = validated_data.get("title", instance.title) instance.pub_time = validated_data.get("pub_time", instance.pub_time) instance.category = validated_data.get("post_category", instance.category) instance.publisher_id = validated_data.get("publisher_id", instance.publisher_id) # 对于多对多的的外键需要判断存不存在author_list if validated_data.get("author_list"): # 用set设置的时候不用拍散,它会自动一个一个的去设置 instance.authors.set(validated_data["author_list"]) print(instance) # instance.save() print(456) return instance # 局部校验方法 def validate_title(self, value): if "小雪" not in value.lower(): raise serializers.ValidationError("不符合社会主义核心价值观") return value # 全局的校验方法 def validate(self, attrs): if attrs["post_category"] == 1: return attrs else: raise serializers.ValidationError("1,难道不好吗?") 正序,反序字段不统一
小结:
- 先去cmd中下载rest_framework框架: pip install djangorestframework
- 在settings的app中注册rest_framework
- app里创建一个py文件导入rest_framework: from rest_framework import serializers
- 创建类继承serializers.Serializer
- 把表中的需要匹配的字段写在类中,注意many=True, 前端显示source="get_字段_display"
来源:https://www.cnblogs.com/ljc-0923/p/10265338.html