如何在Django 3.2.3中实现复合主键?unique_together失效求助
问题解决方法
你的问题根源在于:Django 默认不支持原生复合主键,且你给 c1 设置了 primary_key=True,这会强制将其设为唯一主键,unique_together 仅能添加组合唯一约束,无法替代复合主键的作用;同时 unique_together 在 Django 3.2 中已被标记为弃用,推荐使用 UniqueConstraint。
以下是两种针对性解决方案:
方案1:仅保证字段组合唯一性(官方推荐)
如果不需要将这三个字段作为主键,只是确保它们的组合唯一,修改模型如下:
class myModel(models.Model): _DATABASE = "my_db" c1 = models.CharField(db_column='c1', max_length=20) c2 = models.CharField(db_column='c2', max_length=20) c3 = models.CharField(db_column='c3', max_length=20) c4 = models.CharField(db_column='c4', max_length=50) c5 = models.CharField(db_column='c5', max_length=1024) class Meta: managed = False db_table = 'my_table' constraints = [ models.UniqueConstraint(fields=['c1', 'c2', 'c3'], name='unique_c1_c2_c3') ]
Django 会自动保留默认的 id 主键字段,同时通过 UniqueConstraint 确保 c1、c2、c3 的组合唯一。
方案2:实现真正的复合主键(适配已有数据库)
如果你的数据库表已将 c1、c2、c3 设置为复合主键,需要让 Django 正确识别,可借助第三方库 django-composite-pk:
- 安装依赖库:
pip install django-composite-pk
- 修改模型结构:
from composite_pk.models import CompositePkModel class myModel(CompositePkModel): _DATABASE = "my_db" c1 = models.CharField(db_column='c1', max_length=20) c2 = models.CharField(db_column='c2', max_length=20) c3 = models.CharField(db_column='c3', max_length=20) c4 = models.CharField(db_column='c4', max_length=50) c5 = models.CharField(db_column='c5', max_length=1024) class Meta: managed = False db_table = 'my_table' primary_key = ('c1', 'c2', 'c3')
- 在项目
settings.py的INSTALLED_APPS中添加'composite_pk'。
注意事项
由于你的模型设置了 managed=False,Django 不会修改数据库结构,请确保数据库中已正确创建 c1、c2、c3 的复合主键或唯一约束。
内容的提问来源于stack exchange,提问作者Shreya Ganotra
相关产品推荐
相关产品推荐

