Tomasz Brzezina
Tomasz Brzezina

Reputation: 1534

how to move/upgrade/change model into inherited model

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

Answers (1)

Jamie Cockburn
Jamie Cockburn

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

Related Questions