Repository: jazzband/django-simple-history

Issue:
`save_without_historical_record` doesn't work for manually registered models
In `HistoricalRecords` there is a method `contribute_to_class` which is supposed to add `save_without_historical_record` to model being registered. https://github.com/treyhunner/django-simple-history/blob/master/simple_history/models.py#L38L56 .

However, `contribute_to_class` is _never_ called and so it's impossible to save model without creating a record :(



Discussion:
When Django processes attributes on a model class, if an attribute has a `contribute_to_class` method, that is called in-lieu of adding the attribute to the class directly.  This feature is undocumented (as far as I know) but used by various open source Django apps.

[Here's an explanation of `contribute_to_class`](http://stackoverflow.com/a/2664904/98187).

So I'm not sure what problem you are witnessing, but I doubt it's related to that.  You can sanity check the code by putting a print statement or a breakpoint (`import pdb ; pdb.set_trace()`) at the top of `contribute_to_class` to prove that.

Here is a test that ensures `save_without_historical_record` works: https://github.com/treyhunner/django-simple-history/blob/master/simple_history/tests/tests.py#L93

If I explicitly declare filed `history = HistoricalRecords()` everything works. However, if I just register my model

``` python
simple_history.register(MyModel)
```

`contribute_to_class` isn't called.

Ah good point.  That's a bug.

Pull requests for failing test and working solution welcome.

> Pull requests for failing test and working solution welcome.

I will keep an eye on this, though I'm busy right now.


Resolving patch:
diff --git a/simple_history/__init__.py b/simple_history/__init__.py
--- a/simple_history/__init__.py
+++ b/simple_history/__init__.py
@@ -19,5 +19,6 @@ def register(model, app=None, manager_name='history'):
         records = models.HistoricalRecords()
         records.manager_name = manager_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/models.py b/simple_history/models.py
--- a/simple_history/models.py
+++ b/simple_history/models.py
@@ -42,7 +42,9 @@ def contribute_to_class(self, cls, name):
         self.manager_name = name
         self.module = cls.__module__
         models.signals.class_prepared.connect(self.finalize, sender=cls)
+        self.add_extra_methods(cls)
 
+    def add_extra_methods(self, cls):
         def save_without_historical_record(self, *args, **kwargs):
             """
             Save model without saving a historical record


Test patch:
diff --git a/simple_history/tests/tests.py b/simple_history/tests/tests.py
--- a/simple_history/tests/tests.py
+++ b/simple_history/tests/tests.py
@@ -112,6 +112,10 @@ def test_save_without_historical_record(self):
             'history_type': "~",
         })
 
+    def test_save_without_historical_record_for_registered_model(self):
+        registered_model = ExternalModel3.objects.create(name='registered model')
+        self.assertTrue(hasattr(registered_model, 'save_without_historical_record'))
+
     def test_save_raises_exception(self):
         anthony = Person(name='Anthony Gillard')
         with self.assertRaises(RuntimeError):