如何使用 UUID

How to use UUID

我正在尝试为我的 Django 对象获取唯一 ID。在 Django 1.8 中,他们有 UUIDField。我不确定如何使用此字段为模型中的每个对象生成唯一 ID。

这是我的 UUIDField

import uuid
from django.db import models

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

class Person(models.Model):
    ...
    unique_id = MyUUIDModel()

我可以重现 UUID 模型的 ID,但每次我这样做都会得到完全相同的 ID。例如:

person = Person.objects.get(some_field = some_thing)
id = person.unique_id.id

id 然后每次都给我相同的 id。出了什么问题,我该如何解决?

我不确定您为什么要创建 UUID 模型。可以直接在Person模型中添加uuid字段

class Person(models.Model):
    unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

然后每个人都应该有一个唯一的 ID。如果您希望 uuid 成为主键,您可以这样做:

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

您当前的代码尚未向此人添加字段。它在您执行 MyUUIDModel() 时创建了一个 MyUUIDModel 实例,并将其保存为 class 属性。这样做没有意义,每次加载 models.py 时都会创建 MyUUIDModel。如果你真的想使用 MyUUIDModel,你可以使用 ForeignKey。然后每个人都会 link 到不同的 MyUUIDModel 实例。

class Person(models.Model):
    ...
    unique_id = models.ForeignKey(MyUUIDModel, unique=True)

但是,正如我之前所说,最简单的方法是直接将 UUID 字段添加到人身上。

您可以直接在Person模型中添加id字段作为UUIDField。不需要单独的 MyUUIDModel

我认为您将它与 UUIDField example 中使用的 MyUUIDModel 混淆了,其中 idUUIDField。您可以只使用下面的代码,它会将 UUIDs 用于 id.

import uuid
from django.db import models

class Person(models.Model):
    ...
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) 

在像这样声明您的 Person 模型时,您需要使用作为子 class 创建的 class:

import uuid
from django.db import models

class MyUUIDModel(models.Model):
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

class Person(MyUUIDModel):
  ...

这样 Person 就成为 MyUUIDModel 的子class 并且将继承它的 id 字段定义。

要在 Django 中将 UUID 用于新模型,请参阅Django Docs

但是,如果你想将它用于现有模型unique=True)有对应的数据,你将无法通过上述文档直接进行操作。它将造成 迁移错误 。 要在不丢失数据的情况下执行此操作,请仔细执行 Django Documentation.

中的所有步骤

编辑:其实我错了。还不可能将其实现为 DEFAULT_AUTO_FIELD,因为它必须继承自 IntegerField。这是 the ticket in the django project 的功能请求,以使其成为可能。解决后我会更新我的答案。


从 Django 3.2 开始,如果您想使用 uuid 作为项目范围内所有模型的 pk,则不再需要通用抽象模型。只需定义 DEFAULT_AUTO_FIELD 设置

默认值

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

所以像这样的东西应该可以工作

DEFAULT_AUTO_FIELD = 'django.db.models.UUIDField'

或者更好的是,创建您自己的字段。

DEFAULT_AUTO_FIELD = 'project.common.models.CustomUUIDField'

你在哪里也定义uuid类型等等

如文档中所示,它也可以应用于应用级别。

class MyAppConfig(AppConfig):
    default_auto_field = 'project.common.models.CustomUUIDField'

在模型导入 uuid 中:

import uuid

在class中使用模型:

class Article(TimeStampedModel):
    uuid = models.UUIDField(editable=False, default=uuid.uuid4, unique=True)
    user = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='articles', null=True)
    categories = models.ManyToManyField(ArticleCategory, blank=True)
    title = models.CharField(max_length=500, null=True, blank=True)
    body = RichTextUploadingField(config_name='portal_lobar_config')
    image = models.ImageField(upload_to='article_images/', null=True, blank=True)
    headline = models.BooleanField(default=True)
    tags = models.ManyToManyField(ArticleTag, blank=True)
    slug = AutoSlugField(max_length=500, populate_from='title', unique_with='created__month', null=True)
    published = models.BooleanField(default=False)
    published_at = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['-created']