如何使用 UUID
Posted
技术标签:
【中文标题】如何使用 UUID【英文标题】:How to use UUID 【发布时间】:2015-12-08 07:05:50 【问题描述】:我正在尝试为我的 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。怎么了,怎么解决?
【问题讨论】:
【参考方案1】:我不确定您为什么要创建 UUID 模型。您可以将 uuid 字段直接添加到 Person 模型中。
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
实例,并将其保存为类属性。这样做没有意义,每次加载 models.py 时都会创建 MyUUIDModel
。如果你真的想使用 MyUUIDModel,你可以使用ForeignKey
。然后每个人将链接到不同的 MyUUIDModel 实例。
class Person(models.Model):
...
unique_id = models.ForeignKey(MyUUIDModel, unique=True)
但是,正如我之前所说,最简单的方法是将 UUID 字段直接添加到人员。
【讨论】:
【参考方案2】:您可以在Person
模型中直接将id
字段添加为UUIDField
。不需要单独的MyUUIDModel
。
我认为您将它与UUIDField example 中使用的MyUUIDModel
混淆了,其中id
是UUIDField
。您可以只使用下面的代码,它将使用UUIDs
代替id
。
import uuid
from django.db import models
class Person(models.Model):
...
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
【讨论】:
【参考方案3】:当你像这样声明你的 Person 模型时,你需要使用你创建的类作为子类:
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 的子类,并将继承其 id 字段定义。
【讨论】:
我认为这似乎捕捉到了 OP 的意图? 您应该将MyUUIDModel
抽象化以避免为其创建表格。如果你不这样做,所有子类MyUUIDModel
的类都将与其 ID 共享一个公用表。见docs.djangoproject.com/en/dev/topics/db/models/…【参考方案4】:
编辑:其实我错了。尚不可能将其实现为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'
【讨论】:
在 3.2 中,它说Primary key 'django.db.models.UUIDField' referred by DEFAULT_AUTO_FIELD must subclass AutoField.
是的,这正是我在一个月前添加到此消息的编辑的工单中所写的内容。【参考方案5】:
要在 Django 中将 UUID 用于新模型,请参阅Django Docs。
但是,如果您想将其用于具有与之对应的数据的现有模型(unique=True),您将无法直接执行此操作通过上述文档。它将产生迁移错误。 要做到这一点而不会丢失数据,请仔细按照Django Documentation 的所有步骤操作。
【讨论】:
【参考方案6】:在模型中导入 uuid:
import uuid
在类模型中使用:
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']
【讨论】:
以上是关于如何使用 UUID的主要内容,如果未能解决你的问题,请参考以下文章