【问题标题】:How to keep original ID using UUID as primary key in Django RF project?如何在 Django RF 项目中使用 UUID 作为主键来保留原始 ID?
【发布时间】:2019-06-29 00:37:37
【问题描述】:

我想在我的 DRF 数据库应用程序中使用两个不同的主键。默认情况下,Django“创建” id 为 PK,但是当我尝试在模型中定义新字段(uuid = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)时,未定义默认 id 字段(在 DB 中只存在 uuid)。

如何初始化它们?

我可以提一下,我没有在我的模型中定义 id 字段,因为它是(或者应该是 - 正如我所想的那样)由 DRF 添加。

class Store(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, 
editable=False)
    name = models.CharField(max_length=100, blank=False)
    url = models.URLField(max_length=300, blank=False)
    country = models.CharField(max_length=100, blank=True)

【问题讨论】:

  • 而不是将primary_key设置为True,而是将唯一设置为True。这将是拥有两个唯一字段的标准方式。
  • @5parkp1ug 它是部分好的解决方案,因为它可以工作,但我想在其他模型中使用 uuid 作为外键。是否可以连接例如产品(型号)字段 storeUUID = models.ForeignKey(Store) 即使 uuid 不是 PK 而是唯一的?
  • 您的 UUID 字段是唯一的,您始终可以使用 to_field 参数。检查这个link

标签: mysql django django-rest-framework uuid


【解决方案1】:

主键

在数据库的关系模型中,主键是对一组最小属性(列)的特定选择,它们唯一地指定关系(表)中的元组(行)。

因此,您可以使用默认主键 iduuid(您的选择)。

如果两者都需要,请改用unique=True

class Store(models.Model):
  uuid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)
  name = models.CharField(max_length=100, blank=False)
  url = models.URLField(max_length=300, blank=False)
  country = models.CharField(max_length=100, blank=True)

对于您的情况,您可以将模型更改为

from django.db.models.fields import AutoField
from django.db.models.fields import checks
from django import models

class AutoFieldNonPrimary(AutoField):

    def _check_primary_key(self):
        if self.primary_key:
            return [
                checks.Error(
                    "AutoFieldNonPrimary must not set primary_key=True.",
                    obj=self,
                    id="fields.E100",
                )
            ]
        else:
            return []

class Store(models.Model):
      id = models.AutoFieldNonPrimary(unique=True)
      uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
      name = models.CharField(max_length=100, blank=False)
      url = models.URLField(max_length=300, blank=False)
      country = models.CharField(max_length=100, blank=True)

【讨论】:

  • 你是对的,它工作正常,但我想在不同的模型中使用 Store uuid 作为外键。你能给我一些建议吗?
  • 不幸的是,AutoField 引发错误core.Store.id: (fields.E100) AutoFields must set primary_key=True. 此外,当我尝试删除 uuid 字段并仅将 ID 保留为 autoField(出于测试目的)时,它又出现了另一个错误 AssertionError: Model core.Product can't have more than one AutoField.
  • @Poul3R 为什么你需要id 你已经有uuid 作为pk
  • 一些视图、模型和序列化程序正在使用当前 ID,但我现在不想全部重写。新的应该基于 uuid 而不是简单的 id,这就是我需要它们的原因。您还有其他想法如何解决吗?
猜你喜欢
  • 2018-07-19
  • 2018-10-29
  • 1970-01-01
  • 2020-04-13
  • 2012-12-20
  • 2015-10-27
  • 1970-01-01
  • 2019-10-05
  • 2020-01-30
相关资源
最近更新 更多