13

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?

Community
  • 1
  • 1
Javier Castellanos
  • 9,346
  • 2
  • 15
  • 19

1 Answers1

17

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

Jisson
  • 3,566
  • 8
  • 38
  • 71
knbk
  • 52,111
  • 9
  • 124
  • 122