ham-sandwich
ham-sandwich

Reputation: 4050

Django Models: Common Ancestor Inheritance & Migration

I thought I would up my python game with Django a bit by developing a large scale business app for fun. I seen the need for a common ancestor approach to model inheritence and tried to implement it based on the official documentation. However, I keep getting this very annoying Message which I'm not sure what to do with.

Message

$ python manage.py makemigrations
You are trying to add a non-nullable field 'businessentity_ptr' to business without a default; we can't do that (the database needs something to populate existing rows).

Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py

Models.py

class BusinessEntity(models.Model):
    title = models.CharField(max_length=180)

    def __str__(self):
        return self.title


class Business(BusinessEntity):
    description = models.TextField(max_length=600)
    claimed = models.BooleanField(default=False)
    slug = models.SlugField()
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)

    def __str__(self):
        return self.description

What I've Tried, (which everyone will hate):

  1. Deleting the DB & Re-migrating
  2. setting a default value for all fields
  3. Setting all fields to null = True

I have seen a hack around for this but I don't think it's a good approach. Maybe there is someone out there who understand Django Common Ancestors much better and point me in the right direction.

Upvotes: 2

Views: 2536

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599796

Since your parent model is intended to be abstract, you should mark it as such.

class BusinessEntity(models.Model):
    title = models.CharField(max_length=180)

    class Meta:
        abstract = True

This prevents Django from creating a separate table for it, and therefore needing a _ptr field to point back to it from the subclass. Instead, the table for your subclass will be created to include the inherited field(s) directly.

Upvotes: 10

Related Questions