"We read Knuth so you don't have to."
> I'm trying to get the values from many-to-many relation in the model's
> save() method, but the list of related objects is always empty. After
> the save(), the list has expectd content, but not until the save()
> finishes. Is this normal behaviour and I should look elsewhere to
> process the to-be-saved object depending on related object's values, or
> there is something wrong with my understanding of how Django saves model
Oh my God, I am lost here.
Your understanding is basically correct and at the moment you can't get
to this information directly inside the saving process. Here's a
slightly long explanation of why it's not possible and what we might do
The problem is that a bit of a chicken-and-egg conflict: many-to-many
relations are saved in an intermediate that saves the ids for each pair
of objects. So if object A is related to B1 and B2 via m2m, we save the
[id(A), id(B1)] and [id(A), id(B2)] as two rows in the intermediate
table (by id(A), I mean A's primary key value).
In order to save the pair id(A), id(B1), we need to know both those
values. We only know id(A) after object A has been saved, in the case
where it has an auto-generated primary key value and is being saved for
the first time (i.e. created). So the A.save() method is invoked before
the m2m saving is done. After all the objects have been saved, the
AddManipulator object saves the intermediate relations.
We don't talk about AddManipulator and ChangeManipulator objects much in
Django, because they are an under-the-covers feature. We do talk about
manipulators in general a bit in the (old)forms framework and
AddManipulator and ChangeManipulator are just automatically generated
versions of those.
Now, in the medium- to long-term, we are, of course, moving away from
oldforms to newforms. Part of the reason for this change is that
manipulators turned out to be a bit of a brain-twister in their
Your particular problem, though is one that hasn't yet become easy to
solve. I think we will end up adding a new signal that is emitted when
the m2m relations have been saved, maybe passing the list of saved
objects to the signal handler or something. This hasn't really been
discussed much in detail yet, but it is a missing piece of functionality
that we will solve at some point.