The Django docs recommend copying a model instance thus:
original.pk = None
original.save()
But if you “use inheritance” — apparently meaning if the model’s class is a subclass of a subclass of models.Model — you need to do it slightly differently.
Specifically, the doc says:
Due to how inheritance works, you have to set both pk and id to None:
and gives an example analogous to this:
original.pk = None
original.id = None
original.save()
This seems kludgey. In any case, I’d like to understand what’s going on. Why does using inheritance require you to set the id field to None also? Don’t all Django models inherit from models.Model in any case?
(NOTE: I’m omitting the bit from the doc about copying m2m fields, which incidentally seems even more kludgey.)
It’s because MTI (Multiple Table Inheritance), the type you’re talking about here, stores the object across multiple tables. Take this example:
When you create a
Dog, all the fields onAnimalare saved into the table forAnimal, and just the fields directly onDogare saved to the table forDog. When you lookup theDoglater, Django queries both tables and stitches them together.Both tables, however need primary keys, and Django uses
AutoFields for that, which are simply positive integer fields. SoDoghas an id andAnimalhas an id. Thepkis filled with the id for theAnimalpart because this is the main piece, andDog‘s id doesn’t matter. However, if you’re going to make a copy, you need to copy both pieces. Otherwise, theAnimalpart will of the copy will not get it’s ownDogpart of the copy.