Django同一类对多对多关系报错:需修改related_name
嘿,我太懂你遇到的这个坑了!当同一个模型和另一个模型之间存在多个多对多关系,而且你显式定义了带额外属性的关联表时,Django默认生成的反向关联名称会重复,这就导致了报错。别慌,只要给每个多对多字段指定独一无二的related_name就能解决问题。
问题根源
Django默认会给每个多对多关系生成一个反向关联名称(比如client_set),但如果同一个模型有两个指向同一个目标模型的多对多字段,这个默认名称就会冲突,所以必须手动指定不同的名称。
修改示例代码
假设你的另一个模型是Project,两个多对多关系分别是「客户参与的项目」和「客户收藏的项目」,修改后的代码应该是这样的:
from django.db import models class Client(models.Model): first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) email = models.CharField(max_length=255) password = models.CharField(max_length=255) # 第一个多对多:客户参与的项目,指定反向关联名 participating_projects = models.ManyToManyField( 'Project', through='ClientProjectParticipation', # 你的第一个关联表 related_name='participating_clients' # 从Project反向查Client的属性名 ) # 第二个多对多:客户收藏的项目,指定不同的反向关联名 favorite_projects = models.ManyToManyField( 'Project', through='ClientProjectFavorite', # 你的第二个关联表 related_name='favoriting_clients' # 必须和上面的related_name不一样 ) # 第一个关联表(带额外属性) class ClientProjectParticipation(models.Model): client = models.ForeignKey(Client, on_delete=models.CASCADE) project = models.ForeignKey('Project', on_delete=models.CASCADE) join_date = models.DateField() # 额外属性:加入项目的日期 # 第二个关联表(带额外属性) class ClientProjectFavorite(models.Model): client = models.ForeignKey(Client, on_delete=models.CASCADE) project = models.ForeignKey('Project', on_delete=models.CASCADE) favorite_date = models.DateField() # 额外属性:收藏日期 class Project(models.Model): name = models.CharField(max_length=255) description = models.TextField()
关键说明
related_name要加在每个ManyToManyField的参数里,值必须唯一,不能重复。- 这个名称是给反向查询用的:比如你想查某个项目的所有参与客户,可以用
project.participating_clients.all();查收藏该项目的客户,就用project.favoriting_clients.all()。 - 命名尽量直观,这样后续写代码的时候一眼就能明白这个反向关联的含义。
只要按照这个方式给每个多对多字段指定不同的related_name,冲突报错就会消失啦!
内容的提问来源于stack exchange,提问作者Sadie Flick
相关产品推荐
相关产品推荐

