zoukankan      html  css  js  c++  java
  • python测试开发django-rest-framework-90.反序列化(ModelSerializer)之唯一字段校验UniqueValidator

    前言

    接着前面ModelSerializer 反序列化的时候,写入到数据库时,有些字段是唯一的,不能重复写到数据库,如商品code,具有唯一性。

    UniqueValidator

    UniqueValidator 是校验参数的唯一性,可以传一个queryset对象,也可以自定义message内容,以下是部分源码内容

    class UniqueValidator:
        """
        Validator that corresponds to `unique=True` on a model field.
    
        Should be applied to an individual field on the serializer.
        """
        message = _('This field must be unique.')
    
        def __init__(self, queryset, message=None, lookup='exact'):
            self.queryset = queryset
            self.serializer_field = None
            self.message = message or self.message
            self.lookup = lookup
    

    校验唯一性

    在 Model 模型里面设计了 goods_code 字段是unique=True,在数据库里面具有唯一性

    goods_code = models.CharField(max_length=30,
                                      unique=True,
                                      verbose_name="商品代号")
    

    如果我们保存重复的,会直接返回500 Internal Server Error

    HTTP/1.1 500 Internal Server Error
    Date: Fri, 29 Jan 2021 09:32:34 GMT
    Server: WSGIServer/0.2 CPython/3.6.6
    Content-Type: text/plain; charset=utf-8
    X-Frame-Options: SAMEORIGIN
    Content-Length: 19853
    Vary: Cookie
    
    IntegrityError at /api/v1/goods/
    (1062, "Duplicate entry 'sp100104' for key 'goods_code'")
    

    这说明goods_code 不能重复存到数据库,于是在反序列化的时候,需校验goods_code 的唯一性

    from rest_framework.views import APIView
    from rest_framework import serializers
    from .models import Goods
    from rest_framework import validators
    # 作者-上海悠悠 QQ交流群:717225969
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    class GoodsSerializer(serializers.ModelSerializer):
        """序列化商品models"""
        create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
        update_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False)
    
        # 必传字段 UniqueValidator校验唯一性
        goods_code = serializers.CharField(required=True,
                                           max_length=15,
                                           min_length=8,
                                           validators=[validators.UniqueValidator(queryset=Goods.objects.all())]
                                           )
        goods_stock = serializers.IntegerField(required=True,
                                               min_value=1,
                                               max_value=10000)
        # 忽略字段,设置read_only=True
        goods_status = serializers.IntegerField(read_only=True)
        # 设置write_only=True
        price = serializers.FloatField(write_only=True)
    
        class Meta:
            model = Goods
            # fields = '__all__'  # 返回全部的字段
            # exclude是不包含某些字段
            exclude = ["goods_groupid"]
    

    重复添加,会提示该字段必须唯一。

    也可以加 message 参数自定义校验返回的内容

        goods_code = serializers.CharField(required=True,
                                           max_length=15,
                                           min_length=8,
                                           validators=[validators.UniqueValidator(queryset=Goods.objects.all(), 
                                                                                  message="goods_code 已存在")]
                                           )
    

    如果有多个字段需要联合校验唯一性,可以用UniqueTogetherValidator

  • 相关阅读:
    第四章:(2)原理之 Dubbo 框架设计
    大三学习进度29
    大三学习进度27
    大三学习进度31
    大三学习进度24
    大三学习进度29
    大三学习进度26
    大三学习进度28
    大三学习进度25
    大三学习进度32
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/14346223.html
Copyright © 2011-2022 走看看