Skip to content

populate_history command: support for --default-date #1494

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 2 commits 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
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Unreleased
----------

- Tests are no longer bundled in released wheels (gh-1478)
- Added ``--default-date`` option to ``populate_history`` command (gh-688)

3.9.0 (2025-01-26)
------------------
Expand Down
28 changes: 22 additions & 6 deletions simple_history/management/commands/populate_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ def add_arguments(self, parser):
type=int,
help="Set a custom batch size when bulk inserting historical records.",
)
parser.add_argument(
"--default-date",
action="store",
dest="default_date",
default=None,
help="Set a custom date for the historical records.",
)

def handle(self, *args, **options):
self.verbosity = options["verbosity"]
Expand All @@ -60,7 +67,11 @@ def handle(self, *args, **options):
if self.verbosity >= 1:
self.stdout.write(self.COMMAND_HINT)

self._process(to_process, batch_size=options["batchsize"])
self._process(
to_process,
batch_size=options["batchsize"],
default_date=options["default_date"],
)

def _auto_models(self):
to_process = set()
Expand Down Expand Up @@ -109,11 +120,12 @@ def _model_from_natural_key(self, natural_key):
raise ValueError(msg)
return model, history_model

def _bulk_history_create(self, model, batch_size):
def _bulk_history_create(self, model, batch_size, default_date=None):
"""Save a copy of all instances to the historical model.

:param model: Model you want to bulk create
:param batch_size: number of models to create at once.
:param default_date: date to set for the historical records.
:return:
"""

Expand All @@ -135,7 +147,9 @@ def _bulk_history_create(self, model, batch_size):
# creating them. So we only keep batch_size worth of models in
# historical_instances and clear them after we hit batch_size
if index % batch_size == 0:
history.bulk_history_create(instances, batch_size=batch_size)
history.bulk_history_create(
instances, batch_size=batch_size, default_date=default_date
)

instances = []

Expand All @@ -151,9 +165,11 @@ def _bulk_history_create(self, model, batch_size):

# create any we didn't get in the last loop
if instances:
history.bulk_history_create(instances, batch_size=batch_size)
history.bulk_history_create(
instances, batch_size=batch_size, default_date=default_date
)

def _process(self, to_process, batch_size):
def _process(self, to_process, batch_size, default_date=None):
for model, history_model in to_process:
if history_model.objects.exists():
self.stderr.write(
Expand All @@ -164,6 +180,6 @@ def _process(self, to_process, batch_size):
continue
if self.verbosity >= 1:
self.stdout.write(self.START_SAVING_FOR_MODEL.format(model=model))
self._bulk_history_create(model, batch_size)
self._bulk_history_create(model, batch_size, default_date)
if self.verbosity >= 1:
self.stdout.write(self.DONE_SAVING_FOR_MODEL.format(model=model))
14 changes: 14 additions & 0 deletions simple_history/tests/tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,20 @@ def test_excluded_fields(self):
initial_history_record = PollWithExcludeFields.history.all()[0]
self.assertEqual(initial_history_record.question, poll.question)

def test_populate_with_default_date(self):
date = datetime(2020, 7, 1)
Poll.objects.create(question="Will this populate?", pub_date=datetime.now())
Poll.history.all().delete()
management.call_command(
self.command_name,
auto=True,
default_date=date,
stdout=StringIO(),
stderr=StringIO(),
)
self.assertEqual(Poll.history.all().count(), 1)
self.assertEqual(Poll.history.all()[0].history_date, date)


class TestCleanDuplicateHistory(TestCase):
command_name = "clean_duplicate_history"
Expand Down
16 changes: 16 additions & 0 deletions simple_history/tests/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,22 @@ def test_bulk_manager_with_custom_model_attributes(self):
5,
)

def test_bulk_history_create_with_default_date(self):
date = datetime(2020, 7, 1)
history_manager = get_history_manager_for_model(PollWithHistoricalSessionAttr)
history_manager.bulk_history_create(self.data, default_date=date)

self.assertEqual(PollWithHistoricalSessionAttr.objects.count(), 0)
self.assertEqual(PollWithHistoricalSessionAttr.history.count(), 5)
self.assertTrue(
all(
[
history.history_date == date
for history in PollWithHistoricalSessionAttr.history.all()
]
)
)


class UpdateChangeReasonTestCase(TestCase):
def test_update_change_reason_with_excluded_fields(self):
Expand Down