UUIDField 与带有 UUID 的 Charfield 比较?

Joe*_*ynn 2 django uuid django-models

因此,我一直在 CharField 中使用 UUID 作为我正在从事的项目中的很多事情的 PK,工作正常,没有问题。如果我使用 UUIDField,后端中的某些内容将会出现 UUID 字段的问题(通常是期望 UUID 为字符串的函数)。

使用 UUIDField 与在 CharField 中仅使用“default=uuid.uuid4”相比有什么优势吗?

Wil*_*sem 6

\n

default=uuid.uuid4与仅使用 UUIDField 相比,使用UUIDField有什么优势吗CharField

\n
\n

是的

\n

数据库UUIDField将使用type\xc2\xa0 [postgresql-doc],这会将 UUID 存储为 128 位数量,这比将其存储为字符串更紧凑,字符串需要 32 个字节或因此 256 位(占用两倍的空间)。UUID

\n

如果您使用 a CharField(max_length=36, default=uuid.uuid4),您甚至需要使用36 个字符,因为 aUUID默认情况下会str在中间添加破折号,而不仅仅是使用十六进制值,因此将为这些破折号添加额外的四个字符,这本质上是同样的,从而浪费更多的存储空间。

\n

但除此之外还有其他优点。事实上,它会强制 的长度CharField为 32 个字符,并且格式(如果作为字符串传递)实际上是 UUID。因此,它将对格式进行正确的验证。

\n

它还可以将多种格式的字符串解析为相同的UUID. 例如{12345678-1234-5678-1234-567812345678}12345678123456781234567812345678urn:uuid:12345678-1234-5678-1234-567812345678都会被解析为相同的值,如果您使用简单的 ,则不会出现这种情况,CharField因为它会考虑这些不同的字符串。如果您这样工作:

\n
MyModel.objects.filter(pk=\'urn:uuid:12345678-1234-5678-1234-567812345678\')\n
Run Code Online (Sandbox Code Playgroud)\n

它将检索具有该 UUID 的记录,即使该值以不同的格式存储在数据库中。

\n

它从数据库检索的值包装在类型中UUID。这比string 更“丰富”,并且可以防止犯错误。例如添加两个UUIDs 是没有意义的。的确:

\n
>>> uuid4() + uuid4()\nTraceback (most recent call last):\n  File "<stdin>", line 1, in <module>\nTypeError: unsupported operand type(s) for +: \'UUID\' and \'UUID\'\n
Run Code Online (Sandbox Code Playgroud)\n

而对于字符串,这会导致连接两个字符串。

\n

此外,它使用UUIDField\xc2\xa0 [Django-doc]作为表单字段,这使得将不同的小部件挂接到此类字段更加方便,从而以不同的方式呈现表单。

\n

因此,它提供了更多关于它期望的数据类型的上下文,通常更好的上下文意味着内省模型的模块可以做得更好。

\n