我在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
表,我希望level
和subject_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
。