Skip to content

Commit fa04a3a

Browse files
committed
Merge pull request #196 from Inikup/table-name
Support for custom tables names
2 parents 4492802 + 7522cb9 commit fa04a3a

File tree

7 files changed

+69
-3
lines changed

7 files changed

+69
-3
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Authors
1616
- Joao Pedro Francese
1717
- jofusa
1818
- John Whitlock
19+
- Jonathan Leroy
1920
- Jonathan Sanchez
2021
- Josh Fyne
2122
- Klaas van Schelven

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ tip (unreleased)
66
- Add ability to list history in admin when the object instance is deleted. (gh-72)
77
- Add ability to change history through the admin. (Enabled with the `SIMPLE_HISTORY_EDIT` setting.)
88
- Add Django 1.9 support.
9+
- Support for custom tables names. (gh-196)
910

1011
1.6.3 (2015-07-30)
1112
------------------

docs/advanced.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,29 @@ To change the auto-generated HistoricalRecord models base class from
158158
pub_date = models.DateTimeField('date published')
159159
changed_by = models.ForeignKey('auth.User')
160160
history = HistoricalRecords(bases=[RoutableModel])
161+
162+
Custom history table name
163+
-------------------------
164+
165+
By default, the table name for historical models follow the Django convention
166+
and just add ``historical`` before model name. For instance, if your application
167+
name is ``polls`` and your model name ``Question``, then the table name will be
168+
``polls_historicalquestion``.
169+
170+
You can use the ``table_name`` parameter with both ``HistoricalRecords()`` or
171+
``register()`` to change this behavior.
172+
173+
.. code-block:: python
174+
175+
class Question(models.Model):
176+
question_text = models.CharField(max_length=200)
177+
pub_date = models.DateTimeField('date published')
178+
history = HistoricalRecords(table_name='polls_question_history')
179+
180+
.. code-block:: python
181+
182+
class Question(models.Model):
183+
question_text = models.CharField(max_length=200)
184+
pub_date = models.DateTimeField('date published')
185+
186+
register(Question, table_name='polls_question_history')

simple_history/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
def register(
77
model, app=None, manager_name='history', records_class=None,
8-
**records_config):
8+
table_name=None, **records_config):
99
"""
1010
Create historical model for `model` and attach history manager to `model`.
1111
@@ -14,6 +14,8 @@ def register(
1414
manager_name -- class attribute name to use for historical manager
1515
records_class -- class to use for history relation (defaults to
1616
HistoricalRecords)
17+
table_name -- Custom name for history table (defaults to
18+
'APPNAME_historicalMODELNAME')
1719
1820
This method should be used as an alternative to attaching an
1921
`HistoricalManager` instance directly to `model`.
@@ -24,6 +26,7 @@ def register(
2426
records_class = models.HistoricalRecords
2527
records = records_class(**records_config)
2628
records.manager_name = manager_name
29+
records.table_name = table_name
2730
records.module = app and ("%s.models" % app) or model.__module__
2831
records.add_extra_methods(model)
2932
records.finalize(model)

simple_history/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ class HistoricalRecords(object):
4141
thread = threading.local()
4242

4343
def __init__(self, verbose_name=None, bases=(models.Model,),
44-
user_related_name='+'):
44+
user_related_name='+', table_name=None):
4545
self.user_set_verbose_name = verbose_name
4646
self.user_related_name = user_related_name
47+
self.table_name = table_name
4748
try:
4849
if isinstance(bases, six.string_types):
4950
raise TypeError
@@ -114,6 +115,8 @@ def create_history_model(self, model):
114115
attrs.update(self.get_extra_fields(model, fields))
115116
# type in python2 wants str as a first argument
116117
attrs.update(Meta=type(str('Meta'), (), self.get_meta_options(model)))
118+
if self.table_name is not None:
119+
attrs['Meta'].db_table = self.table_name
117120
name = 'Historical%s' % model._meta.object_name
118121
registered_models[model._meta.db_table] = model
119122
return python_2_unicode_compatible(

simple_history/tests/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,16 @@ class Province(models.Model):
264264
class City(models.Model):
265265
country = models.ForeignKey(Country, db_column='countryCode')
266266
history = HistoricalRecords()
267+
268+
269+
class Contact(models.Model):
270+
name = models.CharField(max_length=30)
271+
email = models.EmailField(max_length=255, unique=True)
272+
history = HistoricalRecords(table_name='contacts_history')
273+
274+
275+
class ContactRegister(models.Model):
276+
name = models.CharField(max_length=30)
277+
email = models.EmailField(max_length=255, unique=True)
278+
279+
register(ContactRegister, table_name='contacts_register_history')

simple_history/tests/tests/test_models.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
ExternalModel1, ExternalModel3, UnicodeVerboseName, HistoricalChoice,
2020
HistoricalState, HistoricalCustomFKError, Series, SeriesWork, PollInfo,
2121
UserAccessorDefault, UserAccessorOverride, Employee, Country, Province,
22-
City
22+
City, Contact, ContactRegister
2323
)
2424
from ..external.models import ExternalModel2, ExternalModel4
2525

@@ -764,3 +764,22 @@ def test_restore_employee(self):
764764
self.assertEqual(original.manager_id, 1)
765765
with self.assertRaises(Employee.DoesNotExist):
766766
original.manager
767+
768+
769+
class CustomTableNameTest1(TestCase):
770+
771+
@staticmethod
772+
def get_table_name(manager):
773+
return manager.model._meta.db_table
774+
775+
def test_custom_table_name(self):
776+
self.assertEqual(
777+
self.get_table_name(Contact.history),
778+
'contacts_history',
779+
)
780+
781+
def test_custom_table_name_from_register(self):
782+
self.assertEqual(
783+
self.get_table_name(ContactRegister.history),
784+
'contacts_register_history',
785+
)

0 commit comments

Comments
 (0)