Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ForeignKeys clashing when using abstract multiple inheritance in Django

I am trying to set up a Django Model that works as a base class for other models. The Base model has two ForeignKey fields to other objects of the same class (TestForeign). I can get the models working using multitable inheritance but I want to use abstract model inheritance because I have read that there are some performance issues when using multitable inheritance.

The following example works when I use multitable inheritance (abstract = False) but fails when I run it with abstract inheritance.

class TestForeign(models.Model):
  test = models.CharField(max_length=100)

class BaseModel(models.Model):
  # specified related_name to avoid reverse accesor clash
  foo = models.ForeignKey(TestForeign, related_name='fooooo')
  bar = models.ForeignKey(TestForeign)

  class Meta:
    abstract = True

class AnotherModel(BaseModel):
  bla = models.CharField(max_length=100)

class YetAnotherModel(BaseModel):
  bla = models.CharField(max_length=100)

When I synchronize the database I get the following error:

ERRORS:
Base.AnotherModel.bar: (fields.E304) Reverse accessor for 'AnotherModel.bar' clashes with reverse accessor for 'YetAnotherModel.bar'.
HINT: Add or change a related_name argument to the definition for 'AnotherModel.bar' or 'YetAnotherModel.bar'.
Base.AnotherModel.bar: (fields.E305) Reverse query name for 'AnotherModel.bar' clashes with reverse query name for 'YetAnotherModel.bar'.
HINT: Add or change a related_name argument to the definition for 'AnotherModel.bar' or 'YetAnotherModel.bar'.
Base.AnotherModel.foo: (fields.E304) Reverse accessor for 'AnotherModel.foo' clashes with reverse accessor for 'YetAnotherModel.foo'.
HINT: Add or change a related_name argument to the definition for 'AnotherModel.foo' or 'YetAnotherModel.foo'.
Base.AnotherModel.foo: (fields.E305) Reverse query name for 'AnotherModel.foo' clashes with reverse query name for 'YetAnotherModel.foo'.
HINT: Add or change a related_name argument to the definition for 'AnotherModel.foo' or 'YetAnotherModel.foo'.
Base.YetAnotherModel.bar: (fields.E304) Reverse accessor for 'YetAnotherModel.bar' clashes with reverse accessor for 'AnotherModel.bar'.
HINT: Add or change a related_name argument to the definition for 'YetAnotherModel.bar' or 'AnotherModel.bar'.
Base.YetAnotherModel.bar: (fields.E305) Reverse query name for 'YetAnotherModel.bar' clashes with reverse query name for 'AnotherModel.bar'.
HINT: Add or change a related_name argument to the definition for 'YetAnotherModel.bar' or 'AnotherModel.bar'.
Base.YetAnotherModel.foo: (fields.E304) Reverse accessor for 'YetAnotherModel.foo' clashes with reverse accessor for 'AnotherModel.foo'.
HINT: Add or change a related_name argument to the definition for 'YetAnotherModel.foo' or 'AnotherModel.foo'.
Base.YetAnotherModel.foo: (fields.E305) Reverse query name for 'YetAnotherModel.foo' clashes with reverse query name for 'AnotherModel.foo'.
HINT: Add or change a related_name argument to the definition for 'YetAnotherModel.foo' or 'AnotherModel.foo'.

Is there any way I can get the references of the base class not to clash in the derived models?

like image 465
Javier Castellanos Avatar asked Jan 16 '15 00:01

Javier Castellanos


People also ask

Does Django support multiple inheritance?

This style is used, if you only want to modify the Python level behaviour of the model, without changing the model's fields. You Inherit from base class and you can add your own properties except fields. base class should not be abstract class. we can not use multiple inheritance in proxy models.

What is abstract inheritance in Django?

What is Django Abstract Base Class Model Inheritance ? According to Django Documentation Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class.

What are types of inheritance in Django?

Multi-table inheritance: Use this when the parent class has common fields, but the parent class table also exists in the database all by itself. Proxy models: Use this when you want to modify the behavior of the parent class, like by changing orderby or a new model manager.


1 Answers

Use %(class)s and %(app_label)s in your related name, as specified in the docs.

like image 186
knbk Avatar answered Sep 27 '22 20:09

knbk