I get this exception:
django.core.exceptions.FieldError:
Local field 'ticket' in class 'SpecialPlugin' clashes with field of similar name from base class 'BasePlugin'
Here are my models:
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')
I only found this note, but in my case the parent class is abstract. I am unsure if it applies here.
I want to give the child class SpecialPlugin
the related name "special" since the related name (%(app_label)s_%(class)s
) of the BasePlugin would break old code.
Is there a way to give SpecialPlugin.ticket the related_name "special"?
2 Answers
Answers 1
It might look like an ugly hack, but you can set a function call to the related_name
argument instead of string. And then override that function in the child class/model.
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'
Answers 2
It looks like the core of the problem is in the overriding of model field Django model inheritance, overriding fields
Simple workaround for you problem will be to decouple BasePlugin to to class without ticket
field and then create a child class that contains ticket
field
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')
Idea is to use BaseWithoutTicketPlugin
when you need to customize ticket
and use BasePlugin
when you don't.
0 comments:
Post a Comment