Django错误消息“在定义中添加一个related_name参数”


72
D:\zjm_code\basic_project>python manage.py syncdb
Error: One or more models did not validate:
topics.topic: Accessor for field 'content_type' clashes with related field 'Cont
entType.topic_set'. Add a related_name argument to the definition for 'content_t
ype'.
topics.topic: Accessor for field 'creator' clashes with related field 'User.crea
ted_topics'. Add a related_name argument to the definition for 'creator'.
topics.topic: Reverse query name for field 'creator' clashes with related field
'User.created_topics'. Add a related_name argument to the definition for 'creato
r'.
topicsMap.topic: Accessor for field 'content_type' clashes with related field 'C
ontentType.topic_set'. Add a related_name argument to the definition for 'conten
t_type'.
topicsMap.topic: Accessor for field 'creator' clashes with related field 'User.c
reated_topics'. Add a related_name argument to the definition for 'creator'.
topicsMap.topic: Reverse query name for field 'creator' clashes with related fie
ld 'User.created_topics'. Add a related_name argument to the definition for 'cre
ator'.

14
如果您不知道“ related_name”参数是什么,则错误消息说明不是很有用。Django“相关对象”文档不一定有帮助;他们没有定义related_name,也没有明确指出您可以为您的related_name发明任何想要的值。
特拉维斯·威尔逊

Answers:


124

您有许多django无法为其生成唯一名称的外键。

您可以通过在模型中的外键字段定义中添加“ related_name”参数来提供帮助。例如:

content_type = ForeignKey(Topic, related_name='topic_content_type')

看到这里更多。 http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name


8
或者只是related_name='+'
Alireza Savand'5

3
@HuckleberryFinn,怎么+办?
Kirk Woll

8
related_name='+'确实可以消除错误,但请注意其目的-选择退出“后退”链接。IE:fooo_set在外部实例上的用法将无法在此处找到正在使用它的实例。
约翰·米

50

例:

class Article(models.Model):
    author = models.ForeignKey('accounts.User')
    editor = models.ForeignKey('accounts.User')
    

这将导致错误,因为Django会尝试自动accounts.User为与like这样的用户的每个外键关系的实例创建一个向后关系user.article_set。此默认方法是不明确的。将user.article_set.all()参考作者字段还是编辑者字段相关的用户文章?

解:

class Article(models.Model):
    author = models.ForeignKey('accounts.User', related_name='author_article_set')
    editor = models.ForeignKey('accounts.User', related_name='editor_article_set')

现在,对于user的实例user,有两种不同的管理器方法:

  1. user.author_article_setuser.author_article_set.all()将返回所有具有author == user的Article对象的Queryset

  2. user.editor_article_setuser.editor_article_set.all()将返回所有具有editor == user的Article对象的Queryset


注意:这是一个旧示例—on_delete现在是的另一个必需参数models.ForeignKey


精美的解释。非常感谢你。
theQuestionMan

这是一个比公认的更好的答案。感谢您的干净的解释和示例!
Ethan Z

13

“如果模型具有ForeignKey,则外键模型的实例将有权访问返回第一个模型的所有实例的Manager。默认情况下,此Manager名为FOO_set,其中FOO是源模型名称,小写。”

但是,如果模型中有多个外键,则django无法为外键管理器生成唯一的名称。
您可以通过在模型中的外键字段定义中添加“ related_name”参数来提供帮助。

参见此处:https : //docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward


1
一半的努力是了解错误消息的含义。我发现这个简单的解释(带有链接)非常有帮助。
Bobble 2015年

1

当我尝试为一个表编写解决方案时会遇到类似的问题,该解决方案会从同一张表中提取足球队的名称。我的桌子看起来像这样:

hometeamID = models.ForeignKey(Team, null=False, on_delete=models.CASCADE)
awayteamID = models.ForeignKey(Team, null=False, on_delete=models.CASCADE)

进行以下更改可以解决我的问题:

hometeamID = models.ForeignKey(Team, null=False, on_delete=models.CASCADE,related_name='home_team')
awayteamID = models.ForeignKey(Team, null=False, on_delete=models.CASCADE,related_name='away_team')

0

但是在我的情况下,我为具有相同型号名称和字段(复制/粘贴;))的某些功能创建了一个单独的应用程序,这是因为发生这种类型的错误,我只是删除了旧型号,代码可以正常工作,
可能会有所帮助对于像我这样的初学者:)



-1

这不是问题的最终答案,但是对于某些人来说,它可能可以解决问题。在签出一个非常老的提交(进入分离的头部状态)然后使代码库恢复最新状态之后,我的项目中出现了相同的错误。解决方案是删除项目中的所有* .pyc文件。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.