django-simple-history icon indicating copy to clipboard operation
django-simple-history copied to clipboard

bulk_update_with_history should use update_fields: history log incorrectly showing phantom changes

Open keyvanm opened this issue 7 months ago • 0 comments

Describe the bug I have a resource in my project that I read data from and bulk push to the Django database. This resource only has a subset of the fields that is stored in Django, hence I pass update_fields to the bulk_update method to make sure the values stored in the DB don't get overwritten by None or other default values that come when you construct the temporary instances from incomplete data to do a bulk update.

Now when using bulk_update_with_history, I can achieve this and have the history objects reflect a push event. But the problem is update_fields don't get passed in history_manager.bulk_history_create, so with the history object has those fields that are not in update_fields set to their default. This is reflected in the admin history log, where you can see that in the actual db instance, the fields that were supposed to be excluded from bulk update aren't updated, but the history log incorrectly shows that they have been updated with the default value set for those fields.

To Reproduce Steps to reproduce the behavior:

  1. Create a model called Page. Give it three fields: name, description and status. Make sure the model is tracked by simple history by adding history = HistoricalRecords(). status should have a default.
  2. Make migrations, migrate, and populate history.
  3. Make a PageAdmin. Make sure it inherits from SimpleHistoryAdmin.
# Assuming the default status is Status.DRAFT
Page.objects.create(name="Home", description="Home page", status=Status.PUBLISHED)  
bulk_update_with_history([
    Page(description="Home page for our project")
], Page, ['description'])
  1. Check the admin page for this object. Confirm that status hasn't changed from the status defined in step 4.
  2. Check the admin history page. Observe that the log incorrectly says that the status has been set to its default during this change. The historical object itself, has status set to its default value.

Expected behavior The change log should not incorrectly say that a change has been made to status. W.r. to the actual historical object itself, it should also not have an incorrect value for the field.

Screenshots If applicable, add screenshots to help explain your problem. In this example the field in question is score, which is not in update_fields.

image ^ it was correctly not updated in the db instance itself

Screenshot 2024-06-28 at 4 22 41 PM ^ but it incorrectly marks a change in the history log

image ^ the history object has an incorrect value

Environment (please complete the following information):

  • OS: Mac OSX
  • Django Simple History Version: 3.7.0
  • Django Version: 5.0
  • Database Version: PostgreSQL 16

Additional context Add any other context about the problem here.

keyvanm avatar Jun 28 '24 23:06 keyvanm