Reputation: 1534
Let's have a model:
class Person(models.Model):
name = models.CharField(max_length=50)
and inherited model:
class User(Person):
email = models.EmailField();
And let's assume, that first I add some instances of person, and it is connected with many other objects in base.
Then Person wants to be a User.
Of course I can delete Person, and add User, but I it's almost impossible to recreate all of connections of Person.
The non django way is just add a field into database Users, using the person id and adding email - it works as expected, but its awful and non django-way.
So how to do it correctly?
Upvotes: 1
Views: 62
Reputation: 7555
This is a bit of a hack, but should work!
person = Person.objects.get(...)
person.__class__ = User
person.email = email
person.save()
You now have a User
object instead!
If you like, you could put this in a decorator:
def upgradable(model):
@classmethod
def upgrade(cls, base, **kwargs):
base.__class__ = cls
for attr, value in kwargs.items():
setattr(base, attr, value)
return base
setattr(model, "upgrade", upgrade)
return model
@upgradable
class User(Person):
email = models.EmailField()
Which you could use like this:
person = Person.objects.get(...)
user = User.upgrade(person, email="[email protected]")
user.save()
Upvotes: 1