Django 2.2 + UUID 作为 ID + 默认值

Posted

技术标签:

【中文标题】Django 2.2 + UUID 作为 ID + 默认值【英文标题】:Django 2.2 + UUID as ID + default values 【发布时间】:2019-08-27 19:25:40 【问题描述】:

所以我有这个作为基础模型:

class BaseModel(models.Model):
    """
    base class for all models enforcing a UUID
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    class Meta:
        abstract = True

以编程方式,从我的 Django 类中,当我从此类派生并调用 .save() 一个新对象时,它是使用新的 UUID 创建的。

但是,当我使用 DataGrip 之类的工具查看数据库架构(最新的 Postgres)时,我发现 id 列在 default 定义中没有任何内容 - 为什么 default=uuid.uuid4 没有转换为数据库模式以某种方式?

当我使用 DataGrip 编辑数据库时,我必须为手动输入的记录手动插入一个新的 UUID 才能正确保存。

有没有办法解决这个问题?在我从 3rd 方数据库客户端添加行时自动生成 UUID?

【问题讨论】:

派生的时候是指子类这个类吗?你打电话给super 我不是在调用 super,但所有子类在 Django 中都可以正常工作。这意味着,它们与基类及其建立的字段有关。我的问题是关于从 3rd 方工具自动生成 UUID,因为数据库模式的“默认”在 python manage migration 之后仍然为空白,因此该工具不起作用。 【参考方案1】:

根据 django 文档here

通用唯一标识符是 AutoField 的一个很好的替代方案 首要的关键。数据库不会为你生成 UUID,所以它是 建议使用默认值:

这意味着,与AutoField 不同,UUIDField 的默认值未在数据库级别实现(或在您的数据库实现此类功能时使用)。它在应用程序级别处理。这就是为什么您必须传递默认值 (uuid.uuid4)。每当插入一条记录时,就会调用uuid.uuid4 函数来生成一个uuid,并将这个值插入到数据库中。如果您进行直接插入,则必须自己处理。

但是,如果您通过在 db 上运行直接查询来设置 id 列的默认值,例如

ALTER TABLE <TABLE_NAME> ALTER COLUMN id SET DEFAULT uuid_generate_v4();

Django 不会抱怨的。它可以从外部 django 应用程序正常工作。

【讨论】:

以上是关于Django 2.2 + UUID 作为 ID + 默认值的主要内容,如果未能解决你的问题,请参考以下文章

在使用 UUID 字段作为主字段的 Django 模型中添加非主键自动字段或“序列”字段

ValidationError:在 Django 中不是有效的 UUID

Django:在 Django 模板引擎中将 uuid 值转换为字符串

Django urls uuid 不起作用

如何使用 UUID

如何将 bigIncrements('id') 转换为 uuid('id') 作为主键?