Django-drf-序列化器

序列化器

介绍

  在Django中,前端传来的数据,一般是JSON格式的数据,获取数据需要通过request.POST.get('xxx)的形式拿到数据,对数据操作完后,返回给前端,也需要转成JSON格式,比较麻烦。

  drf中提供了序列化器的功能,解决了这一过程

功能

  序列化:把模型对象转为字典,经过response后转成JSON字符串

  反序列化:把客户端传来的数据,经过request后转为字典。并完成数据校验功能。序列化器可以把字典转为模型对象。

Serializer

定义一个Serializer类型的序列化器

Serializer类型的序列化器不指定模型表

 1 # 新建一个py文件
 2 from rest_framework import serializers
 3 
 4 
 5 class BookSerializer(serializers.Serializer):
    # 这里没有指定模型表,但是字段还是要对应
6 # 想序列化哪些字段,就写哪些字段 7 id = serializers.CharField() 8 name = serializers.CharField() 9 price = serializers.CharField() 10 author = serializers.CharField() 11 publish = serializers.CharField()

使用Serializer类型的序列化器

过程:通过ORM从数据库获取数据对象-->调用序列化器,序列化数据-->将序列化的数据返回给前端

在视图类中使用

 1 from rest_framework.views import APIView
 2 from api import models
 3 from api import ser
 4 from rest_framework.response import Response
 5 
 6 
 7 class BoosView(APIView):
 8     def get(self,request,pk):
 9         # 根据pk拿数据
10         book_queryset = models.Books.objects.filter(id=pk).first()
11         # 调用序列化组件,序列化数据
12         book_ser = ser.BookSerializer(book_queryset)
13         # 序列化对象.data就是序列化后的字典
14         return Response(book_ser.data)

 

常用选项

- max_length

- min_length

- allow_blank:是否允许为空

- trim_whitespace:是否截断空白字符

- max_value

- min_value

- required:表名该字段在反序列化时必须输入,默认True

- default:反序列化时设置默认值

- allow_null:允许传null,默认False

- validators:该字段使用的验证器

- error_message:包含错误编号与错误信息的字典

- read_only:表名该字段仅用于序列化输出,默认False,若设置为True,在postman中可以看到字段,修改时,不需要传给该字段传值

- write_only:表名该字段段仅用于反序列化输入,默认False,若设置为True,在postman中看不到该字段,修改时,需要给该字段传值

 

局部钩子函数

from rest_framework.exceptions import ValidationError
# 局部钩子
    def validate_price(self, data): # 钩子的名字规则:valiedate_字段名,然后接收一个参数
        # 如price,价格低于10,校验失败
        if float(data) > 10:
            return data # 钩出来的数据要return
        else:
            # 校验失败,抛出异常
            raise ValidationError('价格太低')

 

重写create方法

若序列化类继承了Serializer,客户端请求方式为post的时候,如果去看源码的话,会发现父类BaseSerializer是create方法是直接抛出了异常(NotImplementedError),所以,必须重写create方法

视图类中调用序列化类,通过save方法保存数据

视图类

# 视图类的简单实现
from
rest_framework.response import Response from rest_framework.views import APIView class Test(APIView): def post(self, request, *args, **kwargs): response_msg = {'status': 100, 'msg': '新增成功!'} # 新增数据,不需要去数据库查询 book_ser = ser.BookSerializer(data=request.data, many=True) if book_ser.is_valid(): # 校验通过,保存数据 book_ser.save() # 直接调用会报错,需要重写create方法 response_msg['data'] = book_ser.data else: response_msg['status'] = 102 response_msg['msg'] = '修改失败' response_msg['data'] = book_ser.errors return Response(response_msg)

create方法

   # 在序列化类中重写create方法 
  def create(self, validated_data): instance
= models.Books.objects.create(**validated_data) return instance

 

重写update方法

重写update方法的原因同重写create方法的原因,源码中也是直接抛出了异常

视图类

class Test(APIView):
    def put(self, request, pk):
        response_msg = {'status': 100, 'msg': '新增成功!'}
        # 1 获取数据对象
        user_list = models.User.objects.filter(pk=pk)
        # 2 调用序列化类,得到序列化对象
        user_ser = ser.UserModelSerializer(user_list, request.data, )
        # 3 校验
        if user_ser.is_valid():
            # 校验通过,爆粗年数据
            user_ser.save()  # 直接save会报错,因为会去调用update方法,但是源码中update方法是直接跑异常的
            response_msg['data'] = user_ser.data
        else:
            response_msg['status'] = 103
            response_msg['msg'] = '修改失败'

update方法

# 在序列化类中重写
def update(self, instance, validated_data): # instance就是book这个对象 # validate_data就是校验后的数据 instance.name
= validated_data.get('name') instance.price = validated_data.get('price') instance.author = validated_data.get('author') instance.publish = validated_data.get('publish') # 保存数据 instance.save() # 这里可以直接保存,相当于book.save()因为这个save()是django提供的orm的 return instance

 

全局钩子函数

# 全局钩子
    def validate(self,validate_date):
        author = validate_date.get('author') # 获取校验后的数据
        publish = validate_date.get('publish')
        if author == publish:
            raise ValidationError('作者名字和出版社一样')
        else:
            return validate_date # 钩出来的数据要return

 

使用validators校验

# ser.py 序列化类中写
def check_author(data):
    if data.startswith('sb'):
        raise ValidationError('作者名字不能以sb开头')
    else:
        return data
    
class BookSerializer(serializers.Serializer):
    # 需要序列化哪些字段,就写哪些字段
    author = serializers.CharField(validators=[check_author]) # validators后面可以放函数的内存地址,把author对应的数据传进去做校验

 

ModelSerializer

简介

  如果要操作数据库,强烈推荐使用ModelSerializer,因为指定了model和fields,就和数据库的字段对应起来了,不需要每一个字段都通过serializer去创建。并且通过jwt做多用户登录的校验,也可以在序列化类中做,可以直接去模型表中查到对应的数据对象

定义一个ModelSerializer的序列化类

from rest_framework import serializers
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Books  # 对应上models.py中的模型
        fields = '__all__' # 序列化所有字段 
        # fields = ('name',) # 若不序列化所有字段,写对应的字段名即可,形式为元组或列表

使用

使用序列化类是和Serializer是一样的,区别在于,使用ModelSerializer写序列化类不需要重写create方法和update方法

 

posted @ 2021-12-15 09:21  hushowee  阅读(380)  评论(0)    收藏  举报