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中不同表的外键时,如何将主键列更改为自动递增