summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Hunwicks <roger@tonic-solutions.com>2015-04-15 11:54:57 (GMT)
committerRoger Hunwicks <roger@tonic-solutions.com>2015-04-15 11:54:57 (GMT)
commitd4b494ca3397fe608432b122061fb96d1ba7d500 (patch)
tree949320bf383d46af98f8b9157416ce6eb26b46ec
parent8a7d97e2697baf512a88e7d2c428f5d627e1f5d4 (diff)
downloaddjango-import-export-d4b494ca3397fe608432b122061fb96d1ba7d500.zip
django-import-export-d4b494ca3397fe608432b122061fb96d1ba7d500.tar.gz
django-import-export-d4b494ca3397fe608432b122061fb96d1ba7d500.tar.bz2
Fix #140 - Attributes aren't inherited by subclasses
-rw-r--r--import_export/resources.py25
-rw-r--r--tests/core/tests/resources_tests.py21
2 files changed, 43 insertions, 3 deletions
diff --git a/import_export/resources.py b/import_export/resources.py
index 1de8dc5..2865aae 100644
--- a/import_export/resources.py
+++ b/import_export/resources.py
@@ -109,7 +109,21 @@ class DeclarativeMetaclass(type):
def __new__(cls, name, bases, attrs):
declared_fields = []
-
+ meta = ResourceOptions()
+
+ # If this class is subclassing another Resource, add that Resource's fields.
+ # Note that we loop over the bases in *reverse*. This is necessary in
+ # order to preserve the correct order of fields.
+ for base in bases[::-1]:
+ if hasattr(base, 'fields'):
+ declared_fields = list(six.iteritems(base.fields)) + declared_fields
+ # Collect the Meta options
+ options = getattr(base, 'Meta', None)
+ for option in [option for option in dir(options)
+ if option in dir(meta) and not option.startswith('_')]:
+ setattr(meta, option, getattr(options, option))
+
+ # Add direct fields
for field_name, obj in attrs.copy().items():
if isinstance(obj, Field):
field = attrs.pop(field_name)
@@ -120,8 +134,13 @@ class DeclarativeMetaclass(type):
attrs['fields'] = OrderedDict(declared_fields)
new_class = super(DeclarativeMetaclass, cls).__new__(cls, name,
bases, attrs)
- opts = getattr(new_class, 'Meta', None)
- new_class._meta = ResourceOptions(opts)
+
+ # Add direct options
+ options = getattr(new_class, 'Meta', None)
+ for option in [option for option in dir(options)
+ if option in dir(meta) and not option.startswith('_')]:
+ setattr(meta, option, getattr(options, option))
+ new_class._meta = meta
return new_class
diff --git a/tests/core/tests/resources_tests.py b/tests/core/tests/resources_tests.py
index bbaee0b..be80611 100644
--- a/tests/core/tests/resources_tests.py
+++ b/tests/core/tests/resources_tests.py
@@ -60,6 +60,27 @@ class ResourceTestCase(TestCase):
self.assertEqual(self.my_resource.get_export_headers(),
['email', 'name', 'extra'])
+ # Issue 140 Attributes aren't inherited by subclasses
+ def test_inheritance(self):
+ class A(MyResource):
+ inherited = fields.Field()
+
+ class Meta:
+ import_id_fields = ('email',)
+
+ class B(A):
+ local = fields.Field()
+
+ class Meta:
+ export_order = ('email', 'extra')
+
+ resource = B()
+ self.assertIn('name', resource.fields)
+ self.assertIn('inherited', resource.fields)
+ self.assertIn('local', resource.fields)
+ self.assertEqual(resource.get_export_headers(),
+ ['email', 'extra', 'name', 'inherited', 'local'])
+ self.assertEqual(resource._meta.import_id_fields, ('email',))
class BookResource(resources.ModelResource):
published = fields.Field(column_name='published_date')