我得到了这个例外:
django.core.exceptions.FieldError:
本地字段'票据'在课堂上#SpecialPlugin'与基类' BasePlugin'
中的类似名称字段发生冲突
以下是我的模特:
class BasePlugin(models.Model):
ticket = models.OneToOneField('foobar.ticket', primary_key=True,
related_name='%(app_label)s_%(class)s')
class Meta(IndexImplementation.Meta):
abstract = True
# .. Other stuff which should be available for SpecialPlugin
# and other child classes.
class SpecialPlugin(BasePlugin):
ticket = models.OneToOneField('foobar.ticket', primary_key=True,
related_name='special')
我只有found this note,但在我的情况下,父类是抽象的。我不确定它是否适用于此。
我想给孩子班SpecialPlugin
提供相关名称" special"因为BasePlugin的相关名称(%(app_label)s_%(class)s
)会破坏旧代码。
有没有办法给SpecialPlugin.ticket提供related_name" special"?
答案 0 :(得分:10)
更新
使用django的default_related_name
元选项可以完成类似的事情。
它可能看起来像一个丑陋的黑客,但你可以设置一个函数调用related_name
参数而不是字符串。然后在子类/模型中覆盖该函数。
class BasePlugin(models.Model):
@staticmethod
def get_ticket_related_name():
return '%(app_label)s_%(class)s'
ticket = models.OneToOneField('foobar.ticket', primary_key=True,
related_name=get_ticket_related_name.__func__())
class Meta(IndexImplementation.Meta):
abstract = True
class SpecialPlugin(BasePlugin):
@staticmethod
def get_ticket_related_name():
return 'special'
答案 1 :(得分:0)
看起来问题的核心在于覆盖模型字段Django model inheritance, overriding fields
对您来说,简单的解决方法是将BasePlugin解耦为没有ticket
字段的类,然后创建一个包含ticket
字段的子类
class BaseWithoutTicketPlugin(models.Model):
# .. Other stuff which should be available for SpecialPlugin
# and other child classes.
class Meta(IndexImplementation.Meta):
abstract = True
class BasePlugin(BaseWithoutTicketPlugin):
ticket = models.OneToOneField('foobar.ticket', primary_key=True,
related_name='%(app_label)s_%(class)s')
class Meta(BaseWithoutTicketPlugin.Meta):
abstract = True
class SpecialPlugin(BaseWithoutTicketPlugin):
ticket = models.OneToOneField('foobar.ticket', primary_key=True,
related_name='special')
想法是在您需要自定义BaseWithoutTicketPlugin
时使用ticket
,并在您不需要时使用BasePlugin
。
答案 2 :(得分:0)
在 Meta 类中使用默认相关名称:
class SpecialPlugin(BasePlugin):
class Meta:
default_related_name = 'special_plugins'