反序列化自定义方法验证

如果觉得选项参数验证这些还不够,需要再补充自定义验证行为,可以使用以下三种方法:

单一字段验证

1)validate_<field_name>

<field_name>字段进行验证,如

# 自定义序列化器
class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20,min_length=5)
    bread = serializers.IntegerField(max_value=100,min_value=5)
    # 如果没有选项参数就是必传参数,默认值是required=True
    bpub_date = serializers.DateField()
    # 当required=False,可以不传递参数
    # bpub_date = serializers.DateField(required=False)
    # 当没有传递此字段时,使用的是默认值10,而不会报错
    bcomment = serializers.IntegerField(default=10)

    # 单一字段验证
    def validate_btitle(self, value):

        if value == 'python':
            raise serializers.ValidationError('书名不能是python')
        return value

通过post接收参数进行测试

book_drf目录下views.py代码如下:

import json

from django.http import JsonResponse
from django.views import View

from book_drf.serializer import BookSerialzier
from books.models import BookInfo


class Books(View):
    def get(self, request):
        # 1、查询所有图书对象
        books = BookInfo.objects.all()
        ser = BookSerialzier(books, many=True)
        return JsonResponse(ser.data, safe=False)
    def post(self, request):
        # 1获取前端数据
        data = request.body.decode()  # 得到一个json的字符串
        data_dict = json.loads(data)  # 转换成字典形式
        # 2验证数据
        ser = BookSerialzier(data=data_dict)
        ser.is_valid()  # 验证方法
        print(ser.validated_data)  # 获取验证后的字段数据
        # 3保存数据
        # 4返回结果
        return JsonResponse(ser.errors)


class Book(View):

    def get(self, request):
        book = BookInfo.objects.get(id=1)
        ser = BookSerialzier(book)

        return JsonResponse(ser.data)

Postman发送测试数据如下:

{
    "btitle":"python",
    "bread":5,
    "bpub_date":"1980-5-1"
}

返回结果为:

{
    "btitle": [
        "书名不能是python"
    ]
}

多字段验证

2)validate

在序列化器中需要同时对多个字段进行比较验证时,可以定义validate方法来验证,如

# 自定义序列化器
class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20,min_length=5)
    bread = serializers.IntegerField(max_value=100,min_value=5)
    # 如果没有选项参数就是必传参数,默认值是required=True
    bpub_date = serializers.DateField()
    # 当required=False,可以不传递参数
    # bpub_date = serializers.DateField(required=False)
    # 当没有传递此字段时,使用的是默认值10,而不会报错
    bcomment = serializers.IntegerField(default=10)

    # 单一字段验证
    def validate_btitle(self, value):

        if value == 'python':
            raise serializers.ValidationError('书名不能是python')
        return value

    # 多个字段验证
    def validate(self, attrs):

        if attrs['bread'] < attrs['bcomment']:
            raise serializers.ValidationError('阅读量大于评论量')

        return attrs

Postman发送测试数据如下:

{
    "btitle":"django",
    "bread":5,
    "bpub_date":"1980-5-1"
}

返回结果为:

{
    "non_field_errors": [
        "阅读量大于评论量"
    ]
}

3)validators

在字段中添加validators选项参数,也可以补充验证行为,如

def about_100(value):
    if value == 100:
        raise serializers.ValidationError("评论量不能为100")


# 自定义序列化器
class BookSerialzier(serializers.Serializer):
    # 序列化返回字段
    btitle = serializers.CharField(max_length=20, min_length=5)
    bread = serializers.IntegerField(max_value=100, min_value=5)
    # 如果没有选项参数就是必传参数,默认值是required=True
    bpub_date = serializers.DateField()
    # 当required=False,可以不传递参数
    # bpub_date = serializers.DateField(required=False)
    # 当没有传递此字段时,使用的是默认值10,而不会报错
    bcomment = serializers.IntegerField(default=10, validators=[about_100])

    # 单一字段验证
    def validate_btitle(self, value):

        if value == 'python':
            raise serializers.ValidationError('书名不能是python')
        return value

    # 多个字段验证
    def validate(self, attrs):

        if attrs['bread'] < attrs['bcomment']:
            raise serializers.ValidationError('阅读量大于评论量')

        return attrs

 Postman发送测试数据如下:

{
    "btitle":"django",
    "bread":15,
    "bpub_date":"1980-5-1",
    "bcomment":100
}

返回结果为:

{
    "bcomment": [
        "评论量不能为100"
    ]
}