在Django中实现单独的递增主键

时间:2010-08-10 22:14:48

标签: python django

我正在为我工​​作的公司开发一个内部应用程序,并且我想使用Django来学习它和Python一般,但是我对PK有点麻烦。 / p>

我正在尝试模拟当前应用程序的一部分,其中2个MySQL表,TaskCategory和Tasks,处理需要执行的任务。每个任务都属于TaskCategory,TaskCategory中的每个项目都有自己独立的递增编号。因此,如果“Office”有15个任务,向其添加另一个任务将使其Task.taskid = 16,但向“车辆”添加任务将使Tasks.taskid = 51,而不是17.然后将其用作跟踪号码,例如Vehicles-51任务。

通过在taskcategoryid和taskid(自动递增)组成的Tasks中包含复合主键来实现这种单独的增量。顺便说一下,Tasks.taskcategoryid不是FK(我不认为它可以是,因为它是复合PK的一部分)。

由于Django不喜欢超过1个PK列,因此我在复制此功能时遇到了一些困难。我尝试过unique_together taskid(自动递增PK)和taskcategoryid(FK),我尝试过2个自动递增列(id和taskid)但你不能有多个自动递增列。

使用Django可以实现这种递增功能吗?我宁愿这样做而不必破解源代码,但如果需要的话也会这样做。

1 个答案:

答案 0 :(得分:1)

你的目标是什么?

如果您正在尝试保持与旧应用程序的字段到字段表兼容性,那么您将遇到问题,因为(正如您所观察到的)Django没有compound/composite keys - 它真的喜欢surrogate key。鉴于Django允许的操作以及当前对“正确”数据库设计的思考,代理键是有意义的。

如果您真正想要做的就是保持大多数查询相同(或大部分相似),那么您可以单独保留现有的自然/复合键字段,但删除旧的主键约束,添加新的Django的代理键,然后将Meta data添加到模型中,以声明构成旧复合键的字段为unique_together。 Django将解释它并添加适当的唯一索引。您需要为对象创建添加一些代码来处理递增/分配TaskCategory ID,但最终结果是Django和数据库强制执行所有旧关系。

作为一个例子,这是我在一个桌面游戏锦标赛中跟踪玩家的应用程序模型的一部分:

class Player(models.Model):
    badge = models.IntegerField()
    name  = models.CharField( max_length = 99 )

class Round(models.Model):
    name  = models.CharField( max_length = 9 )
    number = models.IntegerField()

class Table(models.Model):
    round = models.ForeignKey( Round )
    number = models.IntegerField( 'table number')

    class Meta:
        unique_together = ( 'round', 'number' )

class Seat(models.Model):
    table = models.ForeignKey( Table )
    position = models.IntegerField( 'seat number' )
    player = models.ForeignKey( Player )

    class Meta:
        unique_together = ( 'table', 'seat' )

在这种情况下,我使用unique_together来确保表格号码在不同轮次中重复使用,并且座位位置在各个表格中相同,您将永远不会遇到相同的圆形,表格和座位组合一次。