Search code examples
djangomodel

Convert a subclass model instance to another subclass model instance in django?


I have a ModelBase, and ModelA, ModelB.

I want to change ModelA instance to ModelB instance. (I can handle the difference of attributes they have)

I've seen related questions but doesn't quite work for me.

How can I create an inherited django model instance from an existing base model instance?
Change class of child on django models

  • EDIT

When you have Place - Restaurant/Bar relationship,
I think it's quite reasonable to be able to switch a restaurant to a bar.


Solution

  • I would create an entirely new instance of the second model with the same values of their shared attributes, then delete the old one. Seems like the cleanest way to me.

    If ModelBase is abstract:

    instance = ModelA.objects.get(pk=1) #arbitrary        
    
    # find parent class fields:
    fields = [f.name for f in ModelBase._meta.fields]
    
    # get the values from the modelA instance
    values = dict( [(x, getattr(instance, x)) for x in fields] )
    
    #assign same values to new instance of second model
    new_instance = ModelB(**values) 
    
    #add any additional information to new instance here
    
    new_instance.save() #save new one
    instance.delete() # remove the old one
    

    If ModelBase is not abstract, however, you'll have to do an extra workaround:

    fields = [f.name for f in ModelBase._meta.fields if f.name != 'id']
    #... other parts are the same...
    
    new_instance.modelbase_ptr = instance.modelbase_ptr #re-assign related parent
    instance.delete() #delete this first!
    new_instance.save()