Django 1.10 UUIDField 返回字符串或 UUID

Posted

技术标签:

【中文标题】Django 1.10 UUIDField 返回字符串或 UUID【英文标题】:Django 1.10 UUIDField returns either string or UUID 【发布时间】:2017-09-21 07:07:06 【问题描述】:

从 Django 1.9.13 升级到 Django 1.10.7 时,我遇到了 Django 原生 UUIDField 的一个奇怪问题。

我们在自定义用户模型上使用此 UUIDField,例如:

username = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

在 1.9 中,这总是返回一个 UUID 实例。 在 1.10 中,这会在创建新模型实例时返回一个字符串。

比较以下测试示例:

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 的行为方式与它的行为方式不一致。

【问题讨论】:

在创建User 时,在每种情况下您是否都依赖于默认值(uuid.uuid4)?或者有时您是手动提供的? @itzmeontv 1.9.13 和 1.10.7 下列出的陈述是准确的。在这两种情况下,我都使用 UUIDFIeld 默认值,即 uuid.uuid4 可调用。 【参考方案1】:

问题是由 Django 的 AbstractBaseUser 类中的行为改变引起的。 该类收到了一个干净的方法,我在保存时调用了该方法。在新的 clean 方法中调用了 normalize_username 方法,该方法强制用户名为文本。

通过避免对 AbstractBaseUser 的超级调用,我们不再规范化用户名,因为我们的用户名字段是一个 UUID,所以这不是我们想要的。

【讨论】:

以上是关于Django 1.10 UUIDField 返回字符串或 UUID的主要内容,如果未能解决你的问题,请参考以下文章

管理员 search_fields 中的 Django UUIDField

BASE_DIR 返回设置路径而不是项目路径(django 1.10)

在 django 1.10 drf jwt 响应中返回用户名

Django UUIDFIeld unique=True、blank=True 和 null=True 的行为是不是正确?

如何使用 UUID

如何从 django 中的两个不同表中返回数据?