Unexpected serializers.UUIDField behaviour
The issue
When the serializer receives a UUID that we might think is invalid, it gets "cleaned" up and considered valid, returning a completely different UUID.
How to replicate
from django.test import TestCase
from rest_framework import serializers
class TestSerializer(serializers.Serializer):
uuid = serializers.UUIDField(format='hex_verbose')
class SerializerTest(TestCase):
def test_serializer(self):
self.assertTrue(TestSerializer(data={'uuid': '524e802a-061a-4778-b2f9-f5d3d7afd581'}).is_valid())
serializer = TestSerializer(data={'uuid': '524e802_061a-4778-b2f9-f5d3d7afd581'})
self.assertTrue(serializer.is_valid())
self.assertEqual(str(serializer.validated_data['uuid']), '0524e802-061a-4778-b2f9-f5d3d7afd581')
self.assertFalse(TestSerializer(data={'uuid': '524e802a_061a-4778-b2f9-f5d3d7afd581'}).is_valid())
A simple way to replicate is to actually use the uuid package:
import uuid
assert str(uuid.UUID(hex="524e802_061a-4778-b2f9-f5d3d7afd581")) == "0524e802-061a-4778-b2f9-f5d3d7afd581"
Note the differences 524e802_061a and 0524e802-061a
This is not a bug of DRF, it is a Python standardlib bug https://github.com/python/cpython/issues/125651, the fact that you can provide an underscore to UUID constructor means that it is accepting invalid values.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.