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):
ModelSerializer
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