How can you create models (and thus tables) with a compound (composite) primary/unique key using Django?
Asked
Active
Viewed 2.6k times
33

Sam Starling
- 5,298
- 3
- 35
- 52

Viet
- 17,944
- 33
- 103
- 135
-
I've implemented basic support for virtual Composite Keys. Suitable for getting access to an existing db, but probably, for the development it's better to keep using standard django id column. Check my answer here - stackoverflow.com/a/65404017/46548 – kmmbvnr Dec 22 '20 at 06:24
2 Answers
39
Django does not support compound primary keys. You can create a single compound unique key with Meta.unique_together
.

Ignacio Vazquez-Abrams
- 776,304
- 153
- 1,341
- 1,358
-
Thanks Ignacio! How to make this work with Many-to-Many relationship? Will it work? – Viet Feb 16 '10 at 05:46
-
2I'm *really* curious as to what you believe the connection between a compound unique key and a many-to-many relationship is... – Ignacio Vazquez-Abrams Feb 16 '10 at 05:55
-
Say we have 2 entities: Students & Subjects. Students can take many subjects. A join table with compound primary key: Table student_subjects: -------------------------------- student_id subject_id It's a basic technique to create n-to-n relationships. – Viet Feb 16 '10 at 05:58
-
1
-
Regarding many-to-many, the link referenced says: A ManyToManyField cannot be included in unique_together. (It’s not clear what that would even mean!) If you need to validate uniqueness related to a ManyToManyField, try using a signal or an explicit through model. – John Lehmann Dec 27 '15 at 14:27
18
if you want only unique mixed fields together use belowcode:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField()
key2 = models.IntegerField()
But if you want unique together and one of column be primary, set primary
argument for model column, similar below code:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField(primary_key=True)
key2 = models.IntegerField()

M.javid
- 6,387
- 3
- 41
- 56