I can save the mac_address
to upper in database
And the mac_address
value should be unique in database
But if the client send me a lower case json like {"mac_address":'aa:bb:cc:dd:eE'}
and my database already had mac_address
with 'AA:BB:CC:DD:EE'
But client still got 201 created success
Why wouldn't my UniqueValidator
work ??
Please help me find out
views.py
I try ListCreateAPIView
and APIView
Both can't work well I think the problem is UniqueValidator
part
I find the document use validate_<field_name>
But My code not work
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
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. Because the default lookup for UniqueValidator is 'exact'. Whereas you are in need of 'iexact' which does a case insensitive lookup. So change the mac_address
serializer field to :
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. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.