Skip to content

Commit 87a1947

Browse files
committed
Merge pull request #125 from DAV3HIT3/non-rel-support
2 parents 844e5f8 + bad5d95 commit 87a1947

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

simple_history/models.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from django.apps import apps # Django >= 1.7
77
except ImportError:
88
apps = None
9-
from django.db import models
9+
from django.db import models, router
1010
from django.db.models.fields.related import RelatedField
1111
from django.db.models.related import RelatedObject
1212
from django.conf import settings
@@ -268,7 +268,7 @@ def get_field(self, other, cls):
268268
if isinstance(to_field, models.OneToOneField):
269269
field = self.get_one_to_one_field(to_field, other)
270270
elif isinstance(to_field, models.AutoField):
271-
field.__class__ = models.IntegerField
271+
field.__class__ = convert_auto_field(to_field)
272272
else:
273273
field.__class__ = to_field.__class__
274274
excluded_prefixes = ("_", "__")
@@ -320,9 +320,8 @@ def transform_field(field):
320320
"""Customize field appropriately for use in historical model"""
321321
field.name = field.attname
322322
if isinstance(field, models.AutoField):
323-
# The historical model gets its own AutoField, so any
324-
# existing one must be replaced with an IntegerField.
325-
field.__class__ = models.IntegerField
323+
field.__class__ = convert_auto_field(field)
324+
326325
elif isinstance(field, models.FileField):
327326
# Don't copy file, just path.
328327
field.__class__ = models.TextField
@@ -340,6 +339,19 @@ def transform_field(field):
340339
field.serialize = True
341340

342341

342+
def convert_auto_field(field):
343+
"""Convert AutoField to a non-incrementing type
344+
345+
The historical model gets its own AutoField, so any existing one
346+
must be replaced with an IntegerField.
347+
"""
348+
connection = router.db_for_write(field.model)
349+
if settings.DATABASES[connection]['ENGINE'] in ('django_mongodb_engine',):
350+
# Check if AutoField is string for django-non-rel support
351+
return models.TextField
352+
return models.IntegerField
353+
354+
343355
class HistoricalObjectDescriptor(object):
344356
def __init__(self, model):
345357
self.model = model

simple_history/tests/tests/test_models.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
User = get_user_model()
88
except ImportError: # django 1.4 compatibility
99
from django.contrib.auth.models import User
10+
from django.db import models
1011
from django.db.models.loading import get_model
1112
from django.test import TestCase
1213
from django.core.files.base import ContentFile
1314

14-
from simple_history.models import HistoricalRecords
15+
from simple_history.models import HistoricalRecords, convert_auto_field
1516
from simple_history import register
1617
from ..models import (
1718
AdminProfile, Bookcase, MultiOneToOne, Poll, Choice, Restaurant, Person,
@@ -469,3 +470,32 @@ def test_import_related(self):
469470
def test_string_related(self):
470471
field_object = HistoricalState._meta.get_field_by_name('library_id')[0]
471472
self.assertEqual(field_object.related.model, State)
473+
474+
475+
class TestConvertAutoField(TestCase):
476+
"""Check what AutoFields get converted to."""
477+
478+
def setUp(self):
479+
for field in Poll._meta.fields:
480+
if isinstance(field, models.AutoField):
481+
self.field = field
482+
break
483+
484+
def test_relational(self):
485+
"""Relational test
486+
487+
Default Django ORM uses an integer-based auto field.
488+
"""
489+
with self.settings(DATABASES={'default': {
490+
'ENGINE': 'django.db.backends.postgresql_psycopg2'}}):
491+
assert convert_auto_field(self.field) == models.IntegerField
492+
493+
def test_non_relational(self):
494+
"""Non-relational test
495+
496+
MongoDB uses a string-based auto field. We need to make sure
497+
the converted field type is string.
498+
"""
499+
with self.settings(DATABASES={'default': {
500+
'ENGINE': 'django_mongodb_engine'}}):
501+
assert convert_auto_field(self.field) == models.TextField

0 commit comments

Comments
 (0)