Django模型基于外键自动递增主键

Posted

技术标签:

【中文标题】Django模型基于外键自动递增主键【英文标题】:Django Model Auto Increment Primary Key Based on Foreign Key 【发布时间】:2012-02-15 12:37:39 【问题描述】:

我试图弄清楚如何布置我的两个 Django 模型,以便在将新模型保存到数据库时,它的主键会递增,使其成为所有具有相同记录的下一个最高值外键。

这很像this question asked,但我想知道你将如何在 Django 中做到这一点。以下是演示类似情况的问题的摘录:

id | job_id | title
0     1        hi
1     1        hello
2     1        goodbye
0     2        hi
1     2        hello

我知道you can't have multiple primary keys in a Django model,您可以使用unique_together,但文档说它在CREATE 语句中使用了等效的UNIQUE 语句。会

class ModelA(models.Model):
   key = models.PositiveIntegerField(primary_key = True)
   fk = models.ForeignKey(ModelB)

   def Meta(self):
      unique_together = ("key", "fk")

在模型中使用this answer 来完成我正在寻找的东西?模型之间的关系是一个ModelA有多个ModelB,但每个ModelB只有一个ModelA

【问题讨论】:

【参考方案1】:

您必须对模型进行一些更改(如果可能)。所以,ModelA 应该是这样的

class ModelA(models.Model):
    key = models.PositiveIntegerField()
    fk = models.ForeignKey(ModelB)

    def Meta(self):
        unique_together = ("key", "fk")

    def save(self, *args, **kwargs):
        key = cal_key(self.fk)
        self.key = key
        super(ModelA, self).save(*args, **kwargs)

如您所见,我已经覆盖了默认的save method 来计算cal_key 函数中的键值,该函数将fk 作为参数。因此,在模型文件中定义cal_key 函数。

def cal_key(fk):
    present_keys = ModelA.objects.filter(fk=fk).order_by('-key').values_list('key', flat=True)
    if present_keys:
        return present_keys[0]+1
    else:
        return 0

cal_key 函数清楚地表明了您的实际需求。

【讨论】:

谢谢桑迪普。我选择了您的答案,因为它比 Ignacio 的答案更便携。 如果您的应用程序是多线程的,此解决方案是否可能会引发 unique_together 验证错误,因为它会尝试将相同的密钥分配给两个不同的功能,如果它们同时保存? 【参考方案2】:

Jason Ennio 的回答不会让您更新模型,因为 super(ModelA, self).save(*args, **kwargs) 由“if”语句控制。

更新了“保存”方法(缩进)以防止模型在每次更新时更新“键”:

class ModelA(models.Model):
key = models.PositiveIntegerField()
fk = models.ForeignKey(ModelB)

def Meta(self):
    unique_together = ("key", "fk")

def save(self, *args, **kwargs):
    if self._state.adding is True:
        key = cal_key(self.fk)
        self.key = key
        super(ModelA, self).save(*args, **kwargs)

【讨论】:

以上是关于Django模型基于外键自动递增主键的主要内容,如果未能解决你的问题,请参考以下文章

当主键列是mysql中不同表的外键时,如何将主键列更改为自动递增

如何将外键链接到 Oracle 中的自动递增主键?

Django:关于自动递增主键的最佳实践

2016/3/10 数据库简单操作( 创建数据库 创建表 数值类型 主键 外键 自动递增 )

将主键更改为自动递增

sqlserver字段如何自动更新