Skip to content

Commit

Permalink
Merge pull request #125 from DAV3HIT3/non-rel-support
Browse files Browse the repository at this point in the history
  • Loading branch information
macro1 committed Oct 12, 2014
2 parents 844e5f8 + bad5d95 commit 87a1947
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
22 changes: 17 additions & 5 deletions simple_history/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.apps import apps # Django >= 1.7
except ImportError:
apps = None
from django.db import models
from django.db import models, router
from django.db.models.fields.related import RelatedField
from django.db.models.related import RelatedObject
from django.conf import settings
Expand Down Expand Up @@ -268,7 +268,7 @@ def get_field(self, other, cls):
if isinstance(to_field, models.OneToOneField):
field = self.get_one_to_one_field(to_field, other)
elif isinstance(to_field, models.AutoField):
field.__class__ = models.IntegerField
field.__class__ = convert_auto_field(to_field)
else:
field.__class__ = to_field.__class__
excluded_prefixes = ("_", "__")
Expand Down Expand Up @@ -320,9 +320,8 @@ def transform_field(field):
"""Customize field appropriately for use in historical model"""
field.name = field.attname
if isinstance(field, models.AutoField):
# The historical model gets its own AutoField, so any
# existing one must be replaced with an IntegerField.
field.__class__ = models.IntegerField
field.__class__ = convert_auto_field(field)

elif isinstance(field, models.FileField):
# Don't copy file, just path.
field.__class__ = models.TextField
Expand All @@ -340,6 +339,19 @@ def transform_field(field):
field.serialize = True


def convert_auto_field(field):
"""Convert AutoField to a non-incrementing type
The historical model gets its own AutoField, so any existing one
must be replaced with an IntegerField.
"""
connection = router.db_for_write(field.model)
if settings.DATABASES[connection]['ENGINE'] in ('django_mongodb_engine',):
# Check if AutoField is string for django-non-rel support
return models.TextField
return models.IntegerField


class HistoricalObjectDescriptor(object):
def __init__(self, model):
self.model = model
Expand Down
32 changes: 31 additions & 1 deletion simple_history/tests/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
User = get_user_model()
except ImportError: # django 1.4 compatibility
from django.contrib.auth.models import User
from django.db import models
from django.db.models.loading import get_model
from django.test import TestCase
from django.core.files.base import ContentFile

from simple_history.models import HistoricalRecords
from simple_history.models import HistoricalRecords, convert_auto_field
from simple_history import register
from ..models import (
AdminProfile, Bookcase, MultiOneToOne, Poll, Choice, Restaurant, Person,
Expand Down Expand Up @@ -469,3 +470,32 @@ def test_import_related(self):
def test_string_related(self):
field_object = HistoricalState._meta.get_field_by_name('library_id')[0]
self.assertEqual(field_object.related.model, State)


class TestConvertAutoField(TestCase):
"""Check what AutoFields get converted to."""

def setUp(self):
for field in Poll._meta.fields:
if isinstance(field, models.AutoField):
self.field = field
break

def test_relational(self):
"""Relational test
Default Django ORM uses an integer-based auto field.
"""
with self.settings(DATABASES={'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2'}}):
assert convert_auto_field(self.field) == models.IntegerField

def test_non_relational(self):
"""Non-relational test
MongoDB uses a string-based auto field. We need to make sure
the converted field type is string.
"""
with self.settings(DATABASES={'default': {
'ENGINE': 'django_mongodb_engine'}}):
assert convert_auto_field(self.field) == models.TextField

0 comments on commit 87a1947

Please sign in to comment.