Skip to content

Commit

Permalink
Merge ae20ef4 into 38792a7
Browse files Browse the repository at this point in the history
  • Loading branch information
macro1 committed Apr 3, 2015
2 parents 38792a7 + ae20ef4 commit 6580951
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 46 deletions.
14 changes: 10 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ python:
env:
- DJANGO="Django>=1.4,<1.5"
- DJANGO="Django>=1.6,<1.7"
- DJANGO="Django>=1.7,<1.8"
- DJANGO="Django>=1.7,<1.8a"
- DJANGO="Django>=1.8a,<1.9"

install:
- pip install -U coverage coveralls $DJANGO
- pip install -U coverage coveralls
- pip install --pre -U $DJANGO
- python -c 'from __future__ import print_function; import django; print("Django " + django.get_version())'

script: coverage run -a setup.py test
Expand All @@ -22,14 +24,18 @@ matrix:
- python: 2.6
env: DJANGO="Django>=1.6,<1.7"
- python: 2.6
env: DJANGO="Django>=1.7,<1.8"
env: DJANGO="Django>=1.7,<1.8a"
- python: 2.6
env: DJANGO="Django>=1.8a,<1.9"
- python: 3.2
env: DJANGO="Django>=1.4,<1.5"
- python: 3.3
env: DJANGO="Django>=1.4,<1.5"

include:
- python: 3.4
env: DJANGO="Django>=1.7,<1.8"
env: DJANGO="Django>=1.7,<1.8a"
- python: 3.4
env: DJANGO="Django>=1.8a,<1.9"

after_success: coveralls
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Authors
- Trey Hunner
- Ulysses Vilela
- vnagendra
- Rod Xavier Bondoc

Background
==========
Expand Down
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Changes
=======

1.5.x(not yet released)
- Add support for Django 1.8+

1.5.4 (2015-01-03)
------------------
- Fix a bug when models have a ``ForeignKey`` with ``primary_key=True``
Expand Down
46 changes: 31 additions & 15 deletions simple_history/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,37 @@

import threading
import copy
try:
from django.apps import apps
except ImportError: # Django < 1.7
apps = None
import warnings

from django.db import models, router
from django.db.models import loading
from django.db.models.fields.proxy import OrderWrt
from django.db.models.fields.related import RelatedField
from django.db.models.related import RelatedObject
from django.conf import settings
from django.contrib import admin
from django.utils import importlib, six
from django.utils.encoding import python_2_unicode_compatible
from django.utils.encoding import smart_text
from django.utils.timezone import now
from django.utils.translation import string_concat

from .manager import HistoryDescriptor

try:
from django.apps import apps
except ImportError: # Django < 1.7
apps = None
try:
from django.db.models.fields.related import RelatedObject
except ImportError:
RelatedObject = None
try:
from south.modelsinspector import add_introspection_rules
except ImportError: # south not present
pass
else: # south configuration for CustomForeignKeyField
add_introspection_rules(
[], ["^simple_history.models.CustomForeignKeyField"])
from .manager import HistoryDescriptor

registered_models = {}

Expand Down Expand Up @@ -121,18 +128,25 @@ def copy_fields(self, model):
for field in model._meta.fields:
field = copy.copy(field)
field.rel = copy.copy(field.rel)
if isinstance(field, models.ForeignKey):
# Don't allow reverse relations.
# ForeignKey knows best what datatype to use for the column
# we'll used that as soon as it's finalized by copying rel.to
field.__class__ = CustomForeignKeyField
field.rel.related_name = '+'
field.null = True
field.blank = True
if isinstance(field, OrderWrt):
# OrderWrt is a proxy field, switch to a plain IntegerField
field.__class__ = models.IntegerField
transform_field(field)
if isinstance(field, models.ForeignKey):
old_field = field
field = type(field)(
field.rel.to,
related_name='+',
null=True,
blank=True,
primary_key=False,
db_index=True,
serialize=True,
)
field._unique = False
field.name = old_field.name
field.db_constraint = False
else:
transform_field(field)
fields[field.name] = field
return fields

Expand Down Expand Up @@ -227,6 +241,8 @@ def get_history_user(self, instance):
class CustomForeignKeyField(models.ForeignKey):

def __init__(self, *args, **kwargs):
warnings.warn("CustomForeignKeyField is deprecated.",
DeprecationWarning)
super(CustomForeignKeyField, self).__init__(*args, **kwargs)
self.db_constraint = False
self.generate_reverse_relation = False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import unicode_literals

from django.db import models, migrations
import simple_history.models
import django.db.models.deletion
from django.conf import settings


Expand All @@ -30,12 +30,9 @@ class Migration(migrations.Migration):
('history_id', models.AutoField(serialize=False, primary_key=True)),
('history_date', models.DateTimeField()),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL)),
('history_user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True)),
],
options={
'verbose_name': 'historical yar',
'ordering': ('-history_date', '-history_id'),
},
options={'ordering': ('-history_date', '-history_id'), 'get_latest_by': 'history_date', 'verbose_name': 'historical yar'},
bases=(models.Model,),
),
migrations.CreateModel(
Expand All @@ -59,8 +56,8 @@ class Migration(migrations.Migration):
),
migrations.AddField(
model_name='historicalyar',
name='what_id',
field=simple_history.models.CustomForeignKeyField(to='migration_test_app.WhatIMean', blank=True, null=True, related_name='+'),
name='what',
field=models.ForeignKey(related_name='+', db_constraint=False, blank=True, to='migration_test_app.WhatIMean', null=True),
preserve_default=True,
),
]
1 change: 0 additions & 1 deletion simple_history/tests/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,3 @@ def test_deleteting_user(self):

historical_poll = poll.history.all()[0]
self.assertEqual(historical_poll.history_user, None)

37 changes: 20 additions & 17 deletions simple_history/tests/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,29 +327,23 @@ def test_register_custome_records(self):
class CreateHistoryModelTests(TestCase):

def test_create_history_model_with_one_to_one_field_to_integer_field(self):
records = HistoricalRecords()
records.module = AdminProfile.__module__
try:
records.create_history_model(AdminProfile)
except:
register(AdminProfile)
except Exception:
self.fail("SimpleHistory should handle foreign keys to one to one"
"fields to integer fields without throwing an exception")

def test_create_history_model_with_one_to_one_field_to_char_field(self):
records = HistoricalRecords()
records.module = Bookcase.__module__
try:
records.create_history_model(Bookcase)
except:
register(Bookcase)
except Exception:
self.fail("SimpleHistory should handle foreign keys to one to one"
"fields to char fields without throwing an exception.")

def test_create_history_model_with_multiple_one_to_ones(self):
records = HistoricalRecords()
records.module = MultiOneToOne.__module__
try:
records.create_history_model(MultiOneToOne)
except:
register(MultiOneToOne)
except Exception:
self.fail("SimpleHistory should handle foreign keys to one to one"
"fields to one to one fields without throwing an "
"exception.")
Expand Down Expand Up @@ -487,12 +481,20 @@ def test_invalid_bases(self):
self.assertRaises(TypeError, HistoricalRecords, bases=bases)

def test_import_related(self):
field_object = HistoricalChoice._meta.get_field_by_name('poll_id')[0]
self.assertEqual(field_object.related.model, Choice)
field_object = HistoricalChoice._meta.get_field_by_name('poll')[0]
try:
related_model = field_object.rel.related_model
except AttributeError: # Django<1.8
related_model = field_object.related.model
self.assertEqual(related_model, HistoricalChoice)

def test_string_related(self):
field_object = HistoricalState._meta.get_field_by_name('library_id')[0]
self.assertEqual(field_object.related.model, State)
field_object = HistoricalState._meta.get_field_by_name('library')[0]
try:
related_model = field_object.rel.related_model
except AttributeError: # Django<1.8
related_model = field_object.related.model
self.assertEqual(related_model, HistoricalState)

@skipUnless(django.get_version() >= "1.7", "Requires 1.7 migrations")
def test_state_serialization_of_customfk(self):
Expand Down Expand Up @@ -652,7 +654,8 @@ class TestLatest(TestCase):
""""Test behavior of `latest()` without any field parameters"""

def setUp(self):
poll = Poll.objects.create(question="Does `latest()` work?", pub_date=yesterday)
poll = Poll.objects.create(
question="Does `latest()` work?", pub_date=yesterday)
poll.pub_date = today
poll.save()

Expand Down
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ envlist =
py{26,27}-django14,
py{26,27,32,33}-django16,
py{27,32,33,34}-django17,
py{27,32,33,34}-django18,
py{27,32,33,34}-djangotrunk,
docs, flake8

Expand Down Expand Up @@ -31,6 +32,7 @@ deps =
py26: unittest2
django14: Django>=1.4,<1.5
django16: Django>=1.6,<1.7
django17: Django>=1.7,<1.8
django17: Django>=1.7,<1.8a
django18: Django>=1.8a,<1.9a
djangotrunk: https://github.com/django/django/tarball/master
commands = coverage run -a --branch setup.py test

0 comments on commit 6580951

Please sign in to comment.