问题
If I have a polymorphic model:
class Father(polymorphic.model.PolymorphicModel)
and an inheritor class with no extra fields:
class Child(Father)
When I have an instance of Father, how can I convert it to a Child instance?
What I have tried is:
foo = Father.objects.get(pk=1)
# foo is just a Father, no record in Child database table.
foo.polymorphic_ctype = ContentType.objects.get(app_label='myapp', model='child')
foo.save()
But nothing changes. I want foo to be a Child object and need to have this into the child database table.
回答1:
Ok.
After reading this similar post I realized that I needed another assignment:
foo.__class__ = Child
This makes an insertion in the child table otherwise never happened.
回答2:
Django will automatically duplicate entries into the Child in the Father. For the migration that creates the Child class you can simply save new Child objects in the DB (populating them using the __dict__ property of the python object):
Define this function in your migrate file:
def duplicate_Children(apps,schema_editor):
Father = apps.get_model('myapp','Father')
Child= apps.get_model('myapp','Child')
for dad in Father.objects.all():
son = Child()
for attr in dad.__dict__:
son.__dict__[attr]=dad.__dict__[attr]
son.save()
...
Add this to the operations list in the Migrate class:
operations = [migrations.RunPython(duplicate_Children)]
回答3:
For polymorphic model yo can do this:
kclass = YourChangeClass
# With that do the correct insert
self.__class__ = kclass
# With that change the correct model
ct = ContentType.objects.get_for_model(kclass)
self.polymorphic_ctype = ct
# With that set the default values
self.set_default_values()
self.save()
Yo need to define for every class a method that define default values because in other way when do save() fail!.
For example, if you need to pass from A to B:
class A():
attr_1
class B()
attr_2
def set_default_values(self):
self.attr_2 = None
来源:https://stackoverflow.com/questions/39472902/change-the-polymorphic-content-type-of-a-django-model-instance