[英]Django rest framework:UniqueValidator copare the field convert to upper case
I can save the mac_address
to upper in database我可以将
mac_address
保存到数据库中的上层
And the mac_address
value should be unique in database并且
mac_address
值在数据库中应该是唯一的
But if the client send me a lower case json like {"mac_address":'aa:bb:cc:dd:eE'}
但是如果客户端给我发送一个小写的 json,比如
{"mac_address":'aa:bb:cc:dd:eE'}
and my database already had mac_address
with 'AA:BB:CC:DD:EE'
我的数据库已经有
mac_address
和'AA:BB:CC:DD:EE'
But client still got 201 created success
但是客户端还是获得了
201 created success
Why wouldn't my UniqueValidator
work ??为什么我的
UniqueValidator
不起作用?
Please help me find out请帮我找出来
views.py视图.py
I try ListCreateAPIView
and APIView
我尝试
ListCreateAPIView
和APIView
Both can't work well I think the problem is UniqueValidator
part两者都不能很好地工作我认为问题是
UniqueValidator
部分
I find the document use validate_<field_name>
But My code not work我发现文档使用
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)
And the serialize validator needs to convert to lower case first then query the database.并且序列化验证器需要先转换为小写,然后再查询数据库。
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()
define valid_email
method into your serializer在序列化程序中定义
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 valid_email(self,value):
return value.lower()
Your validator should be doing the actual validation:您的验证器应该进行实际验证:
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()
Your UniqueValidator
is working as its expected of it.您的
UniqueValidator
正在按预期工作。 Because the default lookup for UniqueValidator is 'exact'.因为UniqueValidator的默认查找是“精确”。 Whereas you are in need of 'iexact' which does a case insensitive lookup.
而您需要“iexact”,它进行不区分大小写的查找。 So change the
mac_address
serializer field to :因此,将
mac_address
序列化器字段更改为:
mac_address = CharField(max_length=50,
validators=[UniqueValidator(queryset=Data.objects.all(), lookup='iexact')]
)
Note: Using the validate_
prefix method will work but problems may arise when you are trying to use the serializer for partial update.注意:使用
validate_
前缀方法会起作用,但是当您尝试使用序列化程序进行部分更新时可能会出现问题。 At that time you want the serializer to exempt the checkup of uniqueness for mac_address
field or at least exclude the current object from the queryset that you are putting the constraint on.那时您希望序列化程序免除对
mac_address
字段的唯一性检查,或者至少从您施加约束的查询集中排除当前对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.