0

There is an old code with two models shown as below:

class Watermelon(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64, default='Unnamed Watermelon')
    is_allegic = models.BooleanField(default=False)
    use_by = models.DateTimeField()
    seedless = models.BooleanField(default=False)

class Pear(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64, default='Unnamed Pear')
    is_allegic = models.BooleanField(default=False)
    use_by = models.DateTimeField()
    round_shape = models.BooleanField(default=False)

Now I need a generic fruit search related functions so I am trying to use model inheritance without disturbing the original ID numbers from the old data:

class Fruit(models.Model):
    name = models.CharField(max_length=64, default='Unnamed Fruit')
    is_allegic = models.BooleanField(default=False)
    use_by = models.DateTimeField()

class Watermelon(Fruit):
    id = models.AutoField(primary_key=True)
    seedless = models.BooleanField(default=False)

class Pear(Fruit):
    id = models.AutoField(primary_key=True)
    round_shape = models.BooleanField(default=False)

And this causes the conflict for the field 'id', as django doesn't allow to override fields in the subclass models.

I also tried to add a different AutoField 'base_id' in Fruit model, since the ID in the parent model is not going to be used at all. But then I am getting "django.db.utils.ProgrammingError: relation "Fruit" already exists" error when trying to run south makemigrations.

I understand that renumbering all IDs and share them with all subclass models can solve the problem, but I try to avoid this method because those IDs are already referenced by other tables and also used by other systems.

Any advice will be appreciated.

benny
  • 1
  • 2
  • Why do you have different models for Watermelon and Pear in the first place when almost all the fields are the same in the two? Can't you simply have a single FRUIT model and specify an attribute say Fruit_name in it.? – Ankush Raghuvanshi Aug 03 '16 at 17:32
  • My question is about the old code improvement and data migration so nothing can be done for the past. The Fruit thing is just an example; the actual subclass models have more specific fields. – benny Aug 03 '16 at 18:09

1 Answers1

0

It should work if you make the Fruit model abstract:

class Fruit(models.Model):
    name = models.CharField(max_length=64, default='Unnamed Fruit')
    is_allegic = models.BooleanField(default=False)
    use_by = models.DateTimeField()

    class Meta:
        abstract = True

Making it abstract means that you have to subclass it before using it. This allows you to set the primary key on the child class.

solarissmoke
  • 30,039
  • 14
  • 71
  • 73
  • Thanks for the answer. I need a REST based search API for the parent model Fruit, so the actual database table is needed. I try not to query individual subclass models and union results. – benny Aug 04 '16 at 14:36