Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make deep copy of fileds from class attr to instance attr #550

Merged
merged 2 commits into from
May 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 11 additions & 4 deletions import_export/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ class Resource(six.with_metaclass(DeclarativeMetaclass)):
representations and handle importing and exporting data.
"""

def __init__(self):
# The fields class attribute is the *class-wide* definition of
# fields. Because a particular *instance* of the class might want to
# alter self.fields, we create self.fields here by copying cls.fields.
# Instances should always modify self.fields; they should not modify
# cls.fields.
self.fields = deepcopy(self.fields)

@classmethod
def get_result_class(self):
"""
Expand Down Expand Up @@ -231,16 +239,15 @@ def get_fields(self, **kwargs):
"""
return [self.fields[f] for f in self.get_export_order()]

@classmethod
def get_field_name(cls, field):
def get_field_name(self, field):
"""
Returns the field name for a given field.
"""
for field_name, f in cls.fields.items():
for field_name, f in self.fields.items():
if f == field:
return field_name
raise AttributeError("Field %s does not exists in %s resource" % (
field, cls))
field, self.__class__))

def init_instance(self, row=None):
raise NotImplementedError()
Expand Down
36 changes: 34 additions & 2 deletions tests/core/tests/resources_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
WithFloatField,
)

try:
from collections import OrderedDict
except ImportError:
from django.utils.datastructures import SortedDict as OrderedDict

try:
from django.utils.encoding import force_text
except ImportError:
Expand All @@ -45,8 +50,35 @@ def setUp(self):
self.my_resource = MyResource()

def test_fields(self):
fields = self.my_resource.fields
self.assertIn('name', fields)
"""Check that fields were determined correctly """

# check that our fields were determined
self.assertIn('name', self.my_resource.fields)

# check that resource instance fields attr isn't link to resource cls
# fields
self.assertFalse(
MyResource.fields is self.my_resource.fields
)

# dynamically add new resource field into resource instance
self.my_resource.fields.update(
OrderedDict([
('new_field', fields.Field()),
])
)

# check that new field in resource instance fields
self.assertIn(
'new_field',
self.my_resource.fields
)

# check that new field not in resource cls fields
self.assertNotIn(
'new_field',
MyResource.fields
)

def test_field_column_name(self):
field = self.my_resource.fields['name']
Expand Down