summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBojan Mihelac <bmihelac@mihelac.org>2015-04-15 06:16:14 (GMT)
committerBojan Mihelac <bmihelac@mihelac.org>2015-04-15 06:16:14 (GMT)
commit8a7d97e2697baf512a88e7d2c428f5d627e1f5d4 (patch)
tree622e5bdcd44f6762c593a4f55a7a8fddd56f3329
parent7fd35d84ee89d75637c339646f5ab6828e9aad13 (diff)
parentd7bc2f1b82689aedad5b4f3f3433a5bea3aa6f54 (diff)
downloaddjango-import-export-8a7d97e2697baf512a88e7d2c428f5d627e1f5d4.zip
django-import-export-8a7d97e2697baf512a88e7d2c428f5d627e1f5d4.tar.gz
django-import-export-8a7d97e2697baf512a88e7d2c428f5d627e1f5d4.tar.bz2
Merge pull request #233 from bmihelac/django-1.8-fixes
Django 1.8 fixes
-rw-r--r--.travis.yml4
-rw-r--r--docs/changelog.rst2
-rw-r--r--import_export/django_compat.py23
-rw-r--r--import_export/resources.py40
-rw-r--r--tox.ini25
5 files changed, 78 insertions, 16 deletions
diff --git a/.travis.yml b/.travis.yml
index 72e054d..e4c173b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,14 +2,16 @@ language: python
python:
- "2.7"
- "3.3"
+ - "3.4"
env:
- DJANGO=1.4.10
- DJANGO=1.5.5
- DJANGO=1.6.1
- DJANGO=1.7.0
+ - DJANGO=1.8
install:
- pip install -q Django==$DJANGO --use-mirrors
- pip install -e git+https://github.com/kennethreitz/tablib.git#egg=tablib
- pip install -r requirements/base.txt --use-mirrors
script:
- - if [[ $TRAVIS_PYTHON_VERSION != '3.3' || $DJANGO != "1.4.10" ]]; then python tests/manage.py test core --settings=settings; fi
+ - if [[ ($TRAVIS_PYTHON_VERSION != '3.3' && $TRAVIS_PYTHON_VERSION != '3.4') || $DJANGO != "1.4.10" ]]; then python tests/manage.py test core --settings=settings; fi
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 1b1aebf..c531213 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -4,6 +4,8 @@ Changelog for django-import-export
0.2.7 (unreleased)
------------------
+- Django 1.8 compatibility
+
- Call before_import before creating the instance_loader - fixes #193
diff --git a/import_export/django_compat.py b/import_export/django_compat.py
new file mode 100644
index 0000000..c5d1ca4
--- /dev/null
+++ b/import_export/django_compat.py
@@ -0,0 +1,23 @@
+from __future__ import unicode_literals
+
+from django.db import transaction
+
+# transaction management for Django < 1.6
+
+def atomic(*args, **kw):
+ def noop_decorator(func):
+ return func # pass through
+
+ return noop_decorator
+
+def savepoint(*args, **kwargs):
+ transaction.enter_transaction_management()
+ transaction.managed(True)
+
+def savepoint_rollback(*args, **kwargs):
+ transaction.rollback()
+ transaction.leave_transaction_management()
+
+def savepoint_commit(*args, **kwargs):
+ transaction.commit()
+ transaction.leave_transaction_management()
diff --git a/import_export/resources.py b/import_export/resources.py
index ca542d7..1de8dc5 100644
--- a/import_export/resources.py
+++ b/import_export/resources.py
@@ -8,12 +8,11 @@ import traceback
import tablib
from diff_match_patch import diff_match_patch
+from django import VERSION
from django.utils.safestring import mark_safe
from django.utils import six
-from django.db import transaction
from django.db.models.fields import FieldDoesNotExist
from django.db.models.query import QuerySet
-from django.db.models.related import RelatedObject
from django.conf import settings
from .results import Error, Result, RowResult
@@ -23,6 +22,18 @@ from .instance_loaders import (
ModelInstanceLoader,
)
+try:
+ from django.db.transaction import atomic, savepoint, savepoint_rollback, savepoint_commit # noqa
+except ImportError:
+ from .django_compat import atomic, savepoint, savepoint_rollback, savepoint_commit # noqa
+
+
+if VERSION < (1, 8):
+ from django.db.models.related import RelatedObject
+ ForeignObjectRel = RelatedObject
+else:
+ from django.db.models.fields.related import ForeignObjectRel
+ RelatedObject = None
try:
from django.utils.encoding import force_text
@@ -279,6 +290,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
"""
pass
+ @atomic()
def import_data(self, dataset, dry_run=False, raise_errors=False,
use_transactions=None):
"""
@@ -299,8 +311,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
# when transactions are used we want to create/update/delete object
# as transaction will be rolled back if dry_run is set
real_dry_run = False
- transaction.enter_transaction_management()
- transaction.managed(True)
+ sp1 = savepoint()
else:
real_dry_run = dry_run
@@ -311,8 +322,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
result.base_errors.append(Error(repr(e), tb_info))
if raise_errors:
if use_transactions:
- transaction.rollback()
- transaction.leave_transaction_management()
+ savepoint_rollback(sp1)
raise
instance_loader = self._meta.instance_loader_class(self, dataset)
@@ -354,8 +364,7 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
row_result.errors.append(Error(e, tb_info))
if raise_errors:
if use_transactions:
- transaction.rollback()
- transaction.leave_transaction_management()
+ savepoint_rollback(sp1)
six.reraise(*sys.exc_info())
if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP or
self._meta.report_skipped):
@@ -363,10 +372,9 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
if use_transactions:
if dry_run or result.has_errors():
- transaction.rollback()
+ savepoint_rollback(sp1)
else:
- transaction.commit()
- transaction.leave_transaction_management()
+ savepoint_commit(sp1)
return result
@@ -462,14 +470,18 @@ class ModelDeclarativeMetaclass(DeclarativeMetaclass):
# We're not at the last attribute yet, so check that
# we're looking at a relation, and move on to the
# next model.
- if isinstance(f, RelatedObject):
- model = f.model
+ if isinstance(f, ForeignObjectRel):
+ if RelatedObject is None:
+ model = f.related_model
+ else:
+ # Django < 1.8
+ model = f.model
else:
if f.rel is None:
raise KeyError('%s is not a relation' % verbose_path)
model = f.rel.to
- if isinstance(f, RelatedObject):
+ if isinstance(f, ForeignObjectRel):
f = f.field
field = new_class.field_from_django_field(field_name, f,
diff --git a/tox.ini b/tox.ini
index bb2e027..babf6f5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py26-1.4, py27-1.4, py27-tablib-dev-1.4, py27-mysql-innodb-1.4, py27-1.5, py27-1.6, py33-1.6, py27-1.7, py33-1.7
+envlist = py26-1.4, py27-1.4, py27-tablib-dev-1.4, py27-mysql-innodb-1.4, py27-1.5, py27-1.6, py33-1.6, py27-1.7, py33-1.7, py34-1.7, py27-1.8, py33-1.8, py34-1.8
[testenv]
commands=python {toxinidir}/tests/manage.py test core
@@ -54,3 +54,26 @@ basepython = python3.3
deps =
django==1.7.0
-egit+https://github.com/kennethreitz/tablib.git#egg=tablib
+
+[testenv:py34-1.7]
+basepython = python3.4
+deps =
+ django==1.7.0
+ -egit+https://github.com/kennethreitz/tablib.git#egg=tablib
+
+[testenv:py27-1.8]
+basepython = python2.7
+deps =
+ django==1.8
+
+[testenv:py33-1.8]
+basepython = python3.3
+deps =
+ django==1.8
+ -egit+https://github.com/kennethreitz/tablib.git#egg=tablib
+
+[testenv:py34-1.8]
+basepython = python3.4
+deps =
+ django==1.8
+ -egit+https://github.com/kennethreitz/tablib.git#egg=tablib