Search code examples
pythondjangoormmodels

ForeignKey from base class model to inheritor error


I want to make the next models architecture:

class Place(models.Model):
    """
    This is base class for all places like shops, trc, restaurants, etc.
    """
    name = models.CharField(_('Place name'), max_length=255, unique=True, null=True, blank=True)
    partner = models.ForeignKey('Partner', verbose_name=_('Partner'), related_name='places')
    ...
    # next line causes errors
    trc = models.ForeignKey('Trc', related_name='places', null=True, blank=True) 


class Trc(Place):  # Trc is equal to Mall - place which contains shops, cafes, cinemas 
    ...

class Shop(Place):
    ...

class Restaurant(Place):
    ...

Adding 'trc' field in Place model will make querying nice and generic, but when I'm trying to create such tables in db, I'm getting the following error:

CommandError: One or more models did not validate:
partner.trc: Accessor for field 'place_ptr' clashes with field 'Place.trc'. Add a related_name argument to the definition for 'place_ptr'.
partner.trc: Reverse query name for field 'place_ptr' clashes with field 'Place.trc'. Add a related_name argument to the definition for 'place_ptr'.

Playing with related name doesn't help... I really don't want to move 'trc' field in Shop and Restaurant. Thanks


Solution

  • There is no need to add the trc field, because it will already exist. Check out the very similar example in the django docs on multi-table inheritance:

    If you have a Place that is also a Restaurant, you can get from the Place object to the Restaurant object by using the lower-case version of the model name:

        p = Place.objects.get(id=12)
        # If p is a Restaurant object, this will give the child class:
        p.restaurant
        <Restaurant: ...>
    

    However, if p in the above example was not a Restaurant (it had been created directly as a Place object or was the parent of some other class), referring to p.restaurant would raise a Restaurant.DoesNotExist exception.