我的申请包含三个Models
:Users
,Topics
和Responses
。
每个Response
可以在Topic
或另一个Response
处理,但大致相同。为了不复制代码,我认为最好制作一个抽象模型Response
,ResponseResponse
和TopicResponse
继承。
from django.contrib.auth.models import User
from django.db.models import (CASCADE, CharField, DateTimeField,
ForeignKey, ManyToManyField, Model,
TextField)
class Topic(Model):
name = CharField(max_length = 100)
class Response(Model):
body = TextField()
topics = ManyToManyField(Topic)
agreers = ManyToManyField(User)
proposal = TextField()
affirms = ManyToManyField(User, related_name = 'affirmers')
rejects = ManyToManyField(User, related_name = 'rejectors')
class Meta:
abstract = True
class TopicResponse(Response):
responseTo = ForeignKey(Topic, on_delete = CASCADE)
class ResponseResponse(Response):
responseTo = ForeignKey(Response, on_delete = CASCADE)
问题在于User
有两个名为affirmers
的冲突关系,另两个名为rejectors
。
如果我不给他们相关的名字,那么TopicResponse
和ResponseResponse
每个都有三个相互冲突的关系,所有这些关系分别称为TopicResponse
或ResponseResponse
, (一个用于agreers
,一个用于affirms
,一个用于rejects
。
示例错误消息是:
app.TopicResponse.rejects: (fields.E305) Reverse query name for 'TopicResponse.rejects' clashes with reverse query name for 'ResponseResponse.rejects'.
HINT: Add or change a related_name argument to the definition for 'TopicResponse.rejects' or 'ResponseResponse.rejects'.
如果我不使用related_name
参数,我会收到如下错误消息:
app.ResponseResponse.rejects: (fields.E304) Reverse accessor for 'ResponseResponse.rejects' clashes with reverse accessor for 'ResponseResponse.affirms'.
HINT: Add or change a related_name argument to the definition for 'ResponseResponse.rejects' or 'ResponseResponse.affirms'.
我可以做些什么来解决所有这些冲突?我需要以某种方式使用模型的具体实例的名称动态生成related_name
(就像你没有指定它一样)以及关系的名称。
答案 0 :(得分:2)
您必须使相关名称唯一。如docs中所述,您可以添加%(class)s
或%(app_label)s
。然后将这些值替换为子类值:
class Topic(Model):
name = CharField(max_length = 100)
class Response(Model):
body = TextField()
topics = ManyToManyField(Topic)
agreers = ManyToManyField(User)
proposal = TextField()
affirms = ManyToManyField(User, related_name = '%(app_label)s_%(class)saffirmers')
rejects = ManyToManyField(User, related_name = '%(app_label)s_%(class)srejectors')
class Meta:
abstract = True
class TopicResponse(Response):
responseTo = ForeignKey(Topic, on_delete = CASCADE)
class ResponseResponse(Response):
responseTo = ForeignKey(Response, on_delete = CASCADE)