如何在Django中将两个属性一起设置为主键



我在Django中有一个模型:

class Subject(models.Model):
level = models.CharField(max_length=50)
subject_name = models.CharField(max_length=50)
teacher_name = models.ForeignKey(Teacher, on_delete=models.CASCADE)
total_seats = models.IntegerField()
subject_details = models.CharField(max_length=50)

对于Subject表,我希望levelsubject_name一起作为主键。事实上,我不希望任何其他对象具有相同的名称和级别。我知道我可以使用unique_together,但我在哪里提到primary_key = True

。Django不能使用组合主键。这在文件中有规定:

每个模型只需要一个字段就可以具有primary_key=True(显式声明或自动添加(。

常见问题部分中,它还继续使用:

Django模型支持多列主键吗?

。仅支持单列主键。

但这在实践中不是一个问题,因为没有什么可以阻止添加其他约束(使用unique_together模型选项或直接在数据库中创建约束(,以及在该级别强制执行唯一性。单列主键为管理界面等工作所需的;例如,您需要指定要编辑或删除的对象的单个值。

这是一个经常被请求的功能(例如参见这个Django票证(,但它没有实现。这可能会非常麻烦,首先需要更新许多现有的Django工具(例如,JOIN应该用两个键完成,FOREIGN KEY应该生成两个或多个字段,等等(,可能更严重的问题可能是在Django之上构建的大量包,这些包假设主键不是复合键。因此,它将打破Django"生态系统"中的许多包。

有一些包,如django-compositekey[GitHub],旨在实现这一点。但上一次更新是在2014年10月。

不把它作为主键本身不是问题。事实上,Django的GenericForeignKey[Django-doc]只有在主键都是相同类型的情况下才有效。因此,使用unique_together就足够了。通常,这也会在数据库端生成UNIQUE INDEX

我认为你希望这两个字段由数据库索引,因为主键的主要原因是使字段唯一并由DBMS索引,所以你可以在Meta类中使字段unique_together,并在字段args中设置db_index=True

最新更新