博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django:DjangoRestFramework drf 开发3
阅读量:743 次
发布时间:2019-03-21

本文共 4657 字,大约阅读时间需要 15 分钟。

7. 反序列化

反序列化有 验证保存 两个步骤。

1. 验证

实现步骤:

  1. 定义序列化器类型,根据模型类定义、写属性、类型、参数
  2. 创建序列化器对象,以请求报文中的字典为参数
  3. 调用 is_valid() 方法,如果验证通过则返回True,验证失败返回False
  4. 验证通过时可以调用 validated_data 获取验证后的数据
  5. 验证失败可以通过 error_messages 获取错误信息
  6. 指定参数 raise_exception=True 将错误继续抛出

验证有三种方法:根据属性类型、根据属性参数、自定义方法验证。

1. 根据属性的类型验证

CharField、EmailField、IntegerField、DateField等,用户输入类型错误会报属性的类型错误。

2. 属性参数验证

demo:

btitle = serializers.CharField(min_length=3,max_length=10,							  error_messages={
'min_length': '书名必须大于3个字符串', 'max_length': '书名必须小于10个字符串'})bread = serializers.IntegerField(min_value=10, max_value=100)id = serializers.IntegerField(read_only=True)book_type = models.ForeignKey(Books, related_name='hero', on_delete=models.CASCADE, verbose_name='所属分类') # 外键# 主键和关系属性(外键)必须设成只读:read_only = True

3. 自定义方法进行验证

自定义方法验证有三种方式:

  • validate_属性名称() : 针对 特定(单个)属性的值进行验证

    # 验证书名的自定义方法<--在图书的序列化器内def validate_btitle(self, attr):    # attr 是请求报文中书名的数据,比如 笑傲江湖    # 要求: 书名中包含django字符串    if 'django' in attr:    	# 验证正常返回书名btitle        return attr    else:        # 验证失败抛异常文本信息ValidationError        raise serializers.ValidationError('书名中必须包含django')
  • validate() :针对多个值进行验证。内部参数是字典类型

    # 自定义验证方式二: 将多个属性进行验证def validate(self, attrs):    # attrs 字典,可以接收所有请求报文中的数据    # 多用于多个对比,验证: 阅读量必须大于评论量    bread = attrs.get('bread')    bcomment = attrs.get('bcomment')    # 判断两个值都有才可以,request默认是True,我自己前边没指定,因此这个不用验证    if all([bread, bcomment]):        if bread < bcomment:            raise serializers.ValidationError('阅读量必须大于评论量')    return attrs
  • validators=[参数] :参数是方法列表,定义参数的函数,针对特定属性进行验证。(该方法用的不多)

    # 1.定义<---要把定义放到对应的序列化器上边def check(value):    # 验证: value必须是偶数,只判断不符合要求的情况,抛异常,正常不用管    if value % 2 != 0:        raise serializers.ValidationError('必须为偶数')# 2.在序列化器中使用,对bread进行验证<--在bread限制条件内设置	# 因为是列表,因此可以写很多方法	validators=[check]

序列化器内定义反序列化的方法,然后在views视图内使用:

class BooksView(View):	""" 图书类视图 """    def post(self, request):        # 接收        params = json.loads(request.body.decode())        # 把接收的数据赋给data参数        book_ser = BookSerializer(data=params)        # 验证(调用 is_valid() 方法进行验证)        if book_ser.is_valid():            # 验证成功(保存步骤中会在验证成功后保存,此处暂时返回被验证的数据)            return JsonResponse(book_ser.validated_data)        else:            # 验证失败            return JsonResponse(book_ser.errors)

2. 保存

实现步骤:

  1. 在序列化器中定义create()和update()方法
  2. 在视图中创建序列化器对象,调用is_valid()和save()方法

1. 调用序列化对象的save()方法完成保存

serializer.save()
  • save()方法包含createupdate方法,可以自动调用,这两个方法需要自己在序列化器中创建。
  • 如何知道save调用哪个方法:
    查看序列化器内的参数 BookSerializer(instance=None, data=None)
    • 有模型类对象instance,是update操作;
    • 没有模型类对象instance,是create操作。

2. 增加和修改之前先判断

  • 增加 create()

    当调用serializer.save()时,如果是增加就调用此方法,参数 validated_data 表示验证后的数据

    def create(self, validated_data):	# validated_data 表示验证后的数据,是字典类型 key:value	 # 拆包 **validated_data 拆成 key1:value1,key2:value2,...	 book = BookInfo.objects.create(**validated_data)	 return book

    视图函数中创建新增方法:

    class BooksView(View):    """ 图书类视图 """    def post(self, request):        # 接收        params = json.loads(request.body.decode())        # 把接收的数据赋给data参数        book_ser = BookSerializer(data=params)        # 验证(调用 is_valid() 方法进行验证)        if book_ser.is_valid():            # 验证成功(调用序列化器的save()方法进行保存)            book = book_ser.save()            # 验证成功返回被验证的数据            # return JsonResponse(book_ser.validated_data)            # 保存成功之后返回新增的序列化器对象转成的字典数据            book_dict = BookSerializer(book).data            return JsonResponse(book_dict, status=201)        else:            # 验证失败            return JsonResponse(book_ser.errors)
  • 修改 update()

    当调用serializer.save()时,如果是修改就调用此方法,参数 instance 需要被修改的对象,validated_data 验证后的数据

    def update(self, instance, validated_data):	# instance 需要被修改的对象, validated_data 验证后的数据	instance.btitle = validated_data.get('btitle')	instance.bpub_date = validated_data.get('bpub_date')	instance.save()	return instance

    视图函数中创建修改方法:

    class BookView(View):	""" 图书视图 """    def put(self, request, pk):        """ 根据主键修改 """        params = json.loads(request.body.decode())        book = Books.objects.get(pk=pk)        # serializer = BookSerializer(instance=book, data=params)        serializer = BookSerializer(book, data=params)  # instance是第一个参数,可以省略        if serializer.is_valid():            book = serializer.save()            book_dict = BookSerializer(book).data            return JsonResponse(book_dict, status=201)        else:            return JsonResponse(serializer.errors)
  • 说明:(param_dict接收到的数据)

    • 如果进行create添加操作,则serializer=**Serializer(data=param_dict)
    • 如果进行update修改操作,则serializer=**Serializer(模型类对象,data=param_dict)

知识点:

  • 在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到:

    serializer.save(owner=request.user)

转载地址:http://euxgz.baihongyu.com/

你可能感兴趣的文章