Skip to content

Add ignore_saving_historical_record_on_delete flag #736

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/querying_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@ If you want to save a model without a historical record, you can use the followi
poll.save_without_historical_record()


Delete model without saving historical record
---------------------------------------------

If you have a model that will cause a large number of cascading deletions and
you don't wish to save history instances due to performance issues, you can
set ``ignore_saving_historical_record_on_delete`` to ``True`` on ``HistoricalRecord``

.. code-block:: python

class Poll(models.Model):
question = models.CharField(max_length=200)
history = HistoricalRecords(ignore_saving_historical_record_on_delete=True)


Filtering data using a relationship to the model
------------------------------------------------

Expand Down
6 changes: 6 additions & 0 deletions simple_history/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def __init__(
related_name=None,
use_base_model_db=False,
user_db_constraint=True,
ignore_saving_historical_record_on_delete=False,
):
self.user_set_verbose_name = verbose_name
self.user_related_name = user_related_name
Expand All @@ -92,6 +93,9 @@ def __init__(
self.user_setter = history_user_setter
self.related_name = related_name
self.use_base_model_db = use_base_model_db
self.ignore_saving_historical_record_on_delete = (
ignore_saving_historical_record_on_delete
)

if excluded_fields is None:
excluded_fields = []
Expand Down Expand Up @@ -474,6 +478,8 @@ def post_delete(self, instance, using=None, **kwargs):
if self.cascade_delete_history:
manager = getattr(instance, self.manager_name)
manager.using(using).all().delete()
elif getattr(self, "ignore_saving_historical_record_on_delete", False):
return
else:
self.create_historical_record(instance, "-", using=using)

Expand Down
8 changes: 8 additions & 0 deletions simple_history/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ class Choice(models.Model):
votes = models.IntegerField()


class ChoiceWithIgnoredHistoryOnDelete(models.Model):
poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice = models.CharField(max_length=200)
votes = models.IntegerField()

history = HistoricalRecords(ignore_saving_historical_record_on_delete=True)


register(Choice)


Expand Down
16 changes: 16 additions & 0 deletions simple_history/tests/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
CharFieldChangeReasonModel,
CharFieldFileModel,
Choice,
ChoiceWithIgnoredHistoryOnDelete,
City,
ConcreteAttr,
ConcreteExternal,
Expand Down Expand Up @@ -238,6 +239,21 @@ def test_cascade_delete_history(self):
self.assertEqual(len(thames.history.all()), 1)
self.assertEqual(len(nile.history.all()), 0)

def test_ignore_saving_historical_record_on_delete(self):
poll = Poll.objects.create(question="foo", pub_date=today)
choice_with_history = Choice.objects.create(poll=poll, choice="a", votes=1)
choice_without_deletion_history = ChoiceWithIgnoredHistoryOnDelete.objects.create(
poll=poll, choice="c", votes=1
)

self.assertEqual(len(choice_with_history.history.all()), 1)
self.assertEqual(len(choice_without_deletion_history.history.all()), 1)
poll.delete()
self.assertEqual(len(choice_with_history.history.all()), 2)
self.assertFalse(
choice_without_deletion_history.history.filter(history_type="-").exists()
)

def test_save_without_historical_record(self):
pizza_place = Restaurant.objects.create(name="Pizza Place", rating=3)
pizza_place.rating = 4
Expand Down