Django rest framework:UniqueValidator将字段转换为大写

332nm8kg  于 2023-06-25  发布在  Go
关注(0)|答案(3)|浏览(111)

我可以将mac_address保存到数据库中的上层
并且mac_address值在数据库中应该是唯一的
但如果客户端给我发送一个小写的json,比如{"mac_address":'aa:bb:cc:dd:eE'}
我的数据库已经有mac_address'AA:BB:CC:DD:EE'
但客户端仍然得到201 created success
为什么我的UniqueValidator不能工作??
请帮我查一下
views.py
我尝试ListCreateAPIViewAPIView
两者都不能很好地工作,我认为问题是UniqueValidator部分
我发现文档使用validate_<field_name>但我的代码不工作

class DataList(generics.ListCreateAPIView):
    queryset = Data.objects.all()
    serializer_class = DataSerializer

    def perform_create(self, serializer):
        mac_address = self.request.data['mac_address'].upper()
        serializer.save(mac_address=mac_address, datetime=datetime.datetime.now(pytz.utc))
class DataList(APIView):
    def post(self, request, format=None):
        serializer = DataSerializer(data=request.data)
        if serializer.is_valid():
            mac_address = request.data['mac_address'].upper()
            serializer.save(mac_address=mac_address, datetime=datetime.datetime.utcnow().replace(tzinfo=pytz.utc))
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

序列化验证器需要先转换为小写,然后再查询数据库。

class DataSerializer(serializers.ModelSerializer):
    datetime = ReadOnlyField()
    mac_address = CharField(max_length=50,
    validators=[UniqueValidator(queryset=Data.objects.all())]
)
    def validate_mac_address(self,value):
        return value.upper()
vxqlmq5t

vxqlmq5t1#

您的验证器应该执行实际的验证:

class DataSerializer(serializers.ModelSerializer):
    datetime = ReadOnlyField()
    mac_address = CharField(max_length=50)

    def validate_mac_address(self,value):
        if Data.objects.filter(mac_address=value.upper()).exists():
            raise serializers.ValidationError("MAC address should be unique")
        return value.upper()
58wvjzkj

58wvjzkj2#

在序列化器中定义valid_email方法

class DataSerializer(serializers.ModelSerializer):

    email = CharField(
        max_length=255,
        validators=[UniqueValidator(queryset=BlogPost.objects.all())]
    )

    // your content and other stuff goes here

    def validate_email(self,value):
        return value.lower()
fumotvh3

fumotvh33#

您的**UniqueValidator正在按预期工作。因为UniqueValidator**的默认查找为'exact'。而你需要的是'iexact',它不区分大小写。因此,将mac_address序列化器字段更改为:

mac_address = CharField(max_length=50,
    validators=[UniqueValidator(queryset=Data.objects.all(), lookup='iexact')]
)

注意:使用validate_前缀方法可以工作,但是当您尝试使用序列化程序进行部分更新时可能会出现问题。此时,您希望序列化程序免除mac_address字段的唯一性检查,或者至少从您要对其施加约束的查询集中排除当前对象。

相关问题