This repository was archived by the owner on Mar 6, 2023. It is now read-only.
Prevents ModelState instance from being shared by model and clone #9
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I was running into an issue where assigning a new foreign key reference to an object after cloning it was causing the reference to change on both the original and cloned object.
For example:
This was happening because of the
ModelStateobject instance attached to themodel._statekey. When the model is copied withcopy.copy(self.instance)the keys and values in__dict__are copied over to the new instance._stateis included in the__dict__so then both model instances end up pointing at the same instance of the model state, thus causing assignments to one foreign key field to change the value of the other foreign key field.The
ModelStateobject keeps afields_cachedictionary that seems to be the culprit to this duplicate assignment.Additionally,
ModelStatehas anaddingkey that triggers validation uniqueness checks for new objects which could cause additional problems for some models if not reset toTrueSince
_stateis a non-public attribute, setting_state.adding = Trueand_state.fields_cache = {}could potentially break in future versions of Django. Instead, it seemed less brittle to re-initialize_statetoModelState()so it will behave as if it was freshly loaded from the database.I also added tests for this case.