Maybe the Django models API has evolved since this question was asked, but here's how I easily handled it, with a solution that has the advantage of keeping the parent database entry unchanged during the conversion process, ensuring that all related objects in M2M or O2M are retained :
Considering the following models :
class Parent(Model):
pass
class Child(Parent):
child_field = models.CharField()
class Child2(Parent):
child2_field = models.CharField()
In this configuration, Django creates 3 tables parent, child and child2 with a parent_ptr_id OneToOne from child to parent and a parent_ptr_id OneToOne from child2 to parent.
We can represent it such as :
class Parent(Model):
pass
class Child(Model):
parent_ptr = models.OneToOneField(Parent)
child_field = models.CharField()
class Child2(Model):
parent_ptr = models.OneToOneField(Parent)
child2_field = models.CharField()
If we consider a Child model instance that we want to convert into a Child2 model instance, the best option is to :
- Keep the record in the
parent table unchanged
- Delete the record from the
child table (the child_field value will obviously be lost)
- Create a new record in the
child2 table, referencing the record in the parent table
This can be done with the following steps:
object_id = 123 # Child object id
child_object = Child.objects.get(id=object_id)
# Delete the record in the child table, keeping the record in the parent table :
child_object.delete(keep_parents=True)
# Create the record in the child2 table :
child2_object = Child2(parent_ptr_id=object_id)
child2_object.save_base(raw=True)