【问题标题】:Django Model Auto Increment Primary Key Based on Foreign KeyDjango模型基于外键自动递增主键
【发布时间】: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

【问题讨论】:

    标签: python mysql django model


    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2015-11-13
      • 1970-01-01
      • 2020-07-18
      • 1970-01-01
      • 2017-02-20
      • 2018-08-29
      • 2016-04-02
      • 1970-01-01
      • 2013-09-28
      相关资源
      最近更新 更多