Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

django - Issue with ManyToMany Relationships not updating immediately after save

I'm having issues with ManytoMany Relationships that are not updating in a model when I save it (via the admin) and try to use the new value within a function attached to the post_save signal or within the save_model of the associated AdminModel. I've tried to reload the object within those functions by using the get function with the id.. but it still has the old values.

Is this a transaction issue? Is there a signal thrown when the transaction ends?

Thanks,

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When you save a model via admin forms it's not an atomic transaction. The main object gets saved first (to make sure it has a PK), then the M2M is cleared and the new values set to whatever came out of the form. So if you are in the save() of the main object you are in a window of opportunity where the M2M hasn't been updated yet. In fact, if you try to do something to the M2M, the change will get wiped out by the clear(). I ran into this about a year ago.

The code has changed somewhat from the pre-ORM refactor days, but it boils down to code in django.db.models.fields.ManyRelatedObjectsDescriptor and ReverseManyRelatedObjectsDescriptor. Look at their __set__() methods and you'll see manager.clear(); manager.add(*value) That clear() complete cleans out any M2M references for the current main object in that table. The add() then sets the new values.

So to answer your question: yes, this is a transaction issue.

Is there a signal thrown when the transaction ends? Nothing official, but read on:

There was a related thread a few months ago and MonkeyPatching was one method proposed. Grégoire posted a MonkeyPatch for this. I haven't tried it, but it looks like it should work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...