[Solved]-Django – alter bases in migrations

3👍

Had the same issue with the bases and I ended up writing my own migration operation like below. However, worth mention that the whole process looks like follows:

  1. Add a new IntegerField to the model with null=True
  2. Copy data from xxx_ptr to the new field
  3. Remove the xxx_ptrfield
  4. Run the RemoveModelBasesOptions operation
  5. Rename temporary Integer field into id and change it to AutoField
  6. Remove the old model which I inherited from

One thing to note is that if you have models with ForeignKey to your model, it will preserve the link anyway, so it is safe.

class RemoveModelBasesOptions(ModelOptionOperation):
    def __init__(self, name):
        super().__init__(name)

    def deconstruct(self):
        kwargs = {
            'name': self.name,
        }
        return (
            self.__class__.__qualname__,
            [],
            kwargs
        )

    def state_forwards(self, app_label, state):
        model_state = state.models[app_label, self.name_lower]
        model_state.bases = (models.Model,)
        state.reload_model(app_label, self.name_lower, delay=True)

    def database_forwards(self, app_label, schema_editor, from_state,
                          to_state):
        pass

    def database_backwards(self, app_label, schema_editor, from_state,
                           to_state):
        pass

    def describe(self):
        return "Remove bases from the model %s" % self.name

    @property
    def migration_name_fragment(self):
        return 'remove_%s_bases' % self.name_lower

Then, simply call it as an operation in your migration:

class Migration(migrations.Migration):
    dependencies = [
        ('xxxx', '0025_xxxx'),
    ]

    operations = [
        RemoveModelBasesOptions('Foo')
    ]

Leave a comment