Skip to content

Historical records: set the change reason explicitly on the instance #8627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 15, 2021

Conversation

stsewd
Copy link
Member

@stsewd stsewd commented Oct 27, 2021

The implementation of django-simple-history's update_change_reason
is very brittle, as it queries for a previous historical record
that matches the attributes of the instance to update the change_reason,
which could end up updating the wrong record, or not finding it.

https://github.com/jazzband/django-simple-history/blob/b8e43df626a03ce4817beaf6a20995b40a209f37/simple_history/utils.py#L27

I saw this mostly happening when:

  • Saving a team without changing anything (update_change_reason won't
    find the record for some reason)
  • Deleting a team (update_change_reason will override the previous
    record instead)

But simple history also mentions that you can set the change reason
explicitly by setting the _change_reason attribute,
which is more safer as it sets the change_reason at the creation time of
the record.

https://django-simple-history.readthedocs.io/en/latest/historical_model.html#change-reason

I have replaced almost all usages of safe_update_change_reason, except for the ones on apiv3

def perform_create(self, serializer):
obj = serializer.save()
safe_update_change_reason(obj, self.get_change_reason())
return obj
def perform_update(self, serializer):
obj = serializer.save()
safe_update_change_reason(obj, self.get_change_reason())
return obj

as we don't have access to the object before it's updated/created.

Also, maybe we can have a set_change_reason function instead, so it's less error-prone to get the attribute name wrong.

@stsewd stsewd requested a review from a team as a code owner October 27, 2021 23:03
@stsewd stsewd force-pushed the safer-update-change-reason branch from fc616a1 to 3badb44 Compare October 27, 2021 23:08
@stsewd stsewd requested a review from ericholscher October 27, 2021 23:11
The implementation of django-simple-history's `update_change_reason`
is very brittle, as it queries for a previous historical record
that matches the attributes of the instance to update the ``change_reason``,
which could end up updating the wrong record, or not finding it.

https://github.com/jazzband/django-simple-history/blob/b8e43df626a03ce4817beaf6a20995b40a209f37/simple_history/utils.py#L27

I saw this mostly happening when:

- Saving a team without changing anything (update_change_reason won't
  find the record for some reason)
- Deleting a team (update_change_reason will override the previous
  record instead)

But simple history also mentions that you can set the change reason
explicitly by setting the `_change_reason` attribute,
which is more safer as it sets the change_reason at the creation time of
the record.

https://django-simple-history.readthedocs.io/en/latest/historical_model.html#change-reason
@stsewd stsewd force-pushed the safer-update-change-reason branch from 3badb44 to ee17548 Compare October 27, 2021 23:22
@stsewd
Copy link
Member Author

stsewd commented Oct 28, 2021

I just made this a function and was able to use in the update method of apiv3, create is still using the old method since creation happens inside the method and they use .create(**kwargs) instead of creating an instance first.

@stsewd stsewd merged commit 143d116 into master Nov 15, 2021
@stsewd stsewd deleted the safer-update-change-reason branch November 15, 2021 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants