diff --git a/simple_history/__init__.py b/simple_history/__init__.py index 6c959ea2d..ec4e14cff 100755 --- a/simple_history/__init__.py +++ b/simple_history/__init__.py @@ -21,13 +21,14 @@ def register( `HistoricalManager` instance directly to `model`. """ from . import models - if model._meta.db_table not in models.registered_models: - if records_class is None: - records_class = models.HistoricalRecords - records = records_class(**records_config) - records.manager_name = manager_name - records.table_name = table_name - records.module = app and ("%s.models" % app) or model.__module__ - records.add_extra_methods(model) - records.finalize(model) - models.registered_models[model._meta.db_table] = model + + if records_class is None: + records_class = models.HistoricalRecords + + records = records_class(**records_config) + records.manager_name = manager_name + records.table_name = table_name + records.module = app and ("%s.models" % app) or model.__module__ + records.add_extra_methods(model) + records.finalize(model) + models.registered_models[model._meta.db_table] = model diff --git a/simple_history/exceptions.py b/simple_history/exceptions.py new file mode 100644 index 000000000..273dff400 --- /dev/null +++ b/simple_history/exceptions.py @@ -0,0 +1,7 @@ +""" +django-simple-history exceptions and warnings classes. +""" + +class MultipleRegistrationsError(Exception): + """The model has been registered to have history tracking more than once""" + pass diff --git a/simple_history/models.py b/simple_history/models.py index 52c4237b7..967b2353f 100644 --- a/simple_history/models.py +++ b/simple_history/models.py @@ -26,6 +26,7 @@ add_introspection_rules( [], ["^simple_history.models.CustomForeignKeyField"]) +from . import exceptions from .manager import HistoryDescriptor registered_models = {} @@ -75,10 +76,15 @@ def finalize(self, sender, **kwargs): except AttributeError: # called via `register` pass else: - if not hint_class is sender: # set in concrete + if hint_class is not sender: # set in concrete if not (hint_class._meta.abstract and issubclass(sender, hint_class)): # set in abstract return + if hasattr(sender._meta, 'simple_history_manager_attribute'): + raise exceptions.MultipleRegistrationsError('{}.{} registered multiple times for history tracking.'.format( + sender._meta.app_label, + sender._meta.object_name, + )) history_model = self.create_history_model(sender) module = importlib.import_module(self.module) setattr(module, history_model.__name__, history_model) diff --git a/simple_history/tests/tests/test_models.py b/simple_history/tests/tests/test_models.py index e34543431..e1580800e 100644 --- a/simple_history/tests/tests/test_models.py +++ b/simple_history/tests/tests/test_models.py @@ -10,8 +10,8 @@ from django.test import TestCase from django.core.files.base import ContentFile +from simple_history import exceptions, register from simple_history.models import HistoricalRecords, convert_auto_field -from simple_history import register from ..models import ( AdminProfile, Bookcase, MultiOneToOne, Poll, Choice, Voter, Restaurant, Person, FileModel, Document, Book, HistoricalPoll, Library, State, @@ -332,12 +332,8 @@ def test_register_separate_app(self): self.assertEqual(len(user.histories.all()), 1) def test_reregister(self): - register(Restaurant, manager_name='again') - register(User, manager_name='again') - self.assertTrue(hasattr(Restaurant, 'updates')) - self.assertFalse(hasattr(Restaurant, 'again')) - self.assertTrue(hasattr(User, 'histories')) - self.assertFalse(hasattr(User, 'again')) + with self.assertRaises(exceptions.MultipleRegistrationsError): + register(Restaurant, manager_name='again') def test_register_custome_records(self): self.assertEqual(len(Voter.history.all()), 0)