Skip to content

Commit a1f16e0

Browse files
committed
Only allow models to be registered for tracking once
1 parent f7c1c66 commit a1f16e0

File tree

4 files changed

+28
-18
lines changed

4 files changed

+28
-18
lines changed

simple_history/__init__.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ def register(
2121
`HistoricalManager` instance directly to `model`.
2222
"""
2323
from . import models
24-
if model._meta.db_table not in models.registered_models:
25-
if records_class is None:
26-
records_class = models.HistoricalRecords
27-
records = records_class(**records_config)
28-
records.manager_name = manager_name
29-
records.table_name = table_name
30-
records.module = app and ("%s.models" % app) or model.__module__
31-
records.add_extra_methods(model)
32-
records.finalize(model)
33-
models.registered_models[model._meta.db_table] = model
24+
25+
if records_class is None:
26+
records_class = models.HistoricalRecords
27+
28+
records = records_class(**records_config)
29+
records.manager_name = manager_name
30+
records.table_name = table_name
31+
records.module = app and ("%s.models" % app) or model.__module__
32+
records.add_extra_methods(model)
33+
records.finalize(model)
34+
models.registered_models[model._meta.db_table] = model

simple_history/exceptions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
django-simple-history exceptions and warnings classes.
3+
"""
4+
5+
class MultipleRegistrationsError(Exception):
6+
"""The model has been registered to have history tracking more than once"""
7+
pass

simple_history/models.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
add_introspection_rules(
2727
[], ["^simple_history.models.CustomForeignKeyField"])
2828

29+
from . import exceptions
2930
from .manager import HistoryDescriptor
3031

3132
registered_models = {}
@@ -75,10 +76,15 @@ def finalize(self, sender, **kwargs):
7576
except AttributeError: # called via `register`
7677
pass
7778
else:
78-
if not hint_class is sender: # set in concrete
79+
if hint_class is not sender: # set in concrete
7980
if not (hint_class._meta.abstract
8081
and issubclass(sender, hint_class)): # set in abstract
8182
return
83+
if hasattr(sender._meta, 'simple_history_manager_attribute'):
84+
raise exceptions.MultipleRegistrationsError('{}.{} registered multiple times for history tracking.'.format(
85+
sender._meta.app_label,
86+
sender._meta.object_name,
87+
))
8288
history_model = self.create_history_model(sender)
8389
module = importlib.import_module(self.module)
8490
setattr(module, history_model.__name__, history_model)

simple_history/tests/tests/test_models.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from django.test import TestCase
1111
from django.core.files.base import ContentFile
1212

13+
from simple_history import exceptions, register
1314
from simple_history.models import HistoricalRecords, convert_auto_field
14-
from simple_history import register
1515
from ..models import (
1616
AdminProfile, Bookcase, MultiOneToOne, Poll, Choice, Voter, Restaurant,
1717
Person, FileModel, Document, Book, HistoricalPoll, Library, State,
@@ -332,12 +332,8 @@ def test_register_separate_app(self):
332332
self.assertEqual(len(user.histories.all()), 1)
333333

334334
def test_reregister(self):
335-
register(Restaurant, manager_name='again')
336-
register(User, manager_name='again')
337-
self.assertTrue(hasattr(Restaurant, 'updates'))
338-
self.assertFalse(hasattr(Restaurant, 'again'))
339-
self.assertTrue(hasattr(User, 'histories'))
340-
self.assertFalse(hasattr(User, 'again'))
335+
with self.assertRaises(exceptions.MultipleRegistrationsError):
336+
register(Restaurant, manager_name='again')
341337

342338
def test_register_custome_records(self):
343339
self.assertEqual(len(Voter.history.all()), 0)

0 commit comments

Comments
 (0)