Django 1.10 UUIDField returns 字符串或 UUID
Django 1.10 UUIDField returns either string or UUID
从 Django 1.9.13 升级到 Django 1.10.7 时,我遇到了 Django 的本机 UUIDField 的奇怪问题。
我们在自定义用户模型上使用此 UUIDField,例如:
username = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
在 1.9 中,这总是 returns UUID 实例。
在 1.10 中,这个 returns 创建新模型实例时的字符串。
比较以下测试示例:
1.9.13
>>> u = User.objects.last()
>>> u2 = UserFactory()
>>> u3 = User.objects.create()
>>> u.pk
UUID('e7e0f87d-1ed4-4293-829f-b0b745ccd676')
>>> u2.pk
UUID('f8e9a4a9-2265-4cd7-9813-00ffe7fd922a')
>>> u3.pk
UUID('0cb736d7-f8a0-4057-9c89-44fa114f4f82')
1.10.7
>>> u = User.objects.last()
>>> u2 = UserFactory()
>>> u3 = User.objects.create()
>>> u.pk
UUID('e7e0f87d-1ed4-4293-829f-b0b745ccd676')
>>> u2.pk
'f8e9a4a9-2265-4cd7-9813-00ffe7fd922a'
>>> u3.pk
'0cb736d7-f8a0-4057-9c89-44fa114f4f82'
这种差异给各种单元测试带来了问题。我可以通过强制两者都串起来来解决它,但我想了解为什么 UUIDField 的行为方式感觉不一致。
问题是由 Django 的 AbstractBaseUser class 中的行为改变引起的。
class 收到了一个干净的方法,我在保存时调用了它。在新的 clean 方法中调用了一个 normalize_username 方法,强制用户名成为文本。
通过避免对 AbstractBaseUser 的超级调用,我们不再规范化用户名,这不是我们想要的,因为我们的用户名字段是 UUID。
从 Django 1.9.13 升级到 Django 1.10.7 时,我遇到了 Django 的本机 UUIDField 的奇怪问题。
我们在自定义用户模型上使用此 UUIDField,例如:
username = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
在 1.9 中,这总是 returns UUID 实例。 在 1.10 中,这个 returns 创建新模型实例时的字符串。
比较以下测试示例:
1.9.13
>>> u = User.objects.last()
>>> u2 = UserFactory()
>>> u3 = User.objects.create()
>>> u.pk
UUID('e7e0f87d-1ed4-4293-829f-b0b745ccd676')
>>> u2.pk
UUID('f8e9a4a9-2265-4cd7-9813-00ffe7fd922a')
>>> u3.pk
UUID('0cb736d7-f8a0-4057-9c89-44fa114f4f82')
1.10.7
>>> u = User.objects.last()
>>> u2 = UserFactory()
>>> u3 = User.objects.create()
>>> u.pk
UUID('e7e0f87d-1ed4-4293-829f-b0b745ccd676')
>>> u2.pk
'f8e9a4a9-2265-4cd7-9813-00ffe7fd922a'
>>> u3.pk
'0cb736d7-f8a0-4057-9c89-44fa114f4f82'
这种差异给各种单元测试带来了问题。我可以通过强制两者都串起来来解决它,但我想了解为什么 UUIDField 的行为方式感觉不一致。
问题是由 Django 的 AbstractBaseUser class 中的行为改变引起的。 class 收到了一个干净的方法,我在保存时调用了它。在新的 clean 方法中调用了一个 normalize_username 方法,强制用户名成为文本。
通过避免对 AbstractBaseUser 的超级调用,我们不再规范化用户名,这不是我们想要的,因为我们的用户名字段是 UUID。