Skip to content

Commit

Permalink
Only allow models to be registered for tracking once
Browse files Browse the repository at this point in the history
  • Loading branch information
macro1 committed Dec 31, 2015
1 parent f7c1c66 commit a1f16e0
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 18 deletions.
21 changes: 11 additions & 10 deletions simple_history/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions simple_history/exceptions.py
Original file line number Diff line number Diff line change
@@ -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
8 changes: 7 additions & 1 deletion simple_history/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
add_introspection_rules(
[], ["^simple_history.models.CustomForeignKeyField"])

from . import exceptions
from .manager import HistoryDescriptor

registered_models = {}
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 3 additions & 7 deletions simple_history/tests/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a1f16e0

Please sign in to comment.