Skip to content

Updated ObjectField to allow for unmapped keys #302

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

Merged
merged 6 commits into from
Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions django_elasticsearch_dsl/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ def _get_inner_field_data(self, obj, field_value_to_ignore=None):
obj, field_value_to_ignore
)

if not data and obj and isinstance(obj, dict):
data = obj

return data

def get_value_from_instance(self, instance, field_value_to_ignore=None):
Expand All @@ -128,8 +131,8 @@ def get_value_from_instance(self, instance, field_value_to_ignore=None):
is_iterable = bool(iter(objs))
except TypeError:
is_iterable = False
if is_iterable:

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment here why we are excluding the dictionary?
Something like

Suggested change
# Need to exclude dictionary, as it is iterable, but the full data need to be indexed.

if is_iterable and not isinstance(objs, dict):
return [
self._get_inner_field_data(obj, field_value_to_ignore)
for obj in objs if obj != field_value_to_ignore
Expand Down
77 changes: 77 additions & 0 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,36 @@ def test_get_value_from_instance(self):
'last_name': "bar",
})

def test_get_value_from_instance_with_partial_properties(self):
field = ObjectField(
attr='person',
properties={
'first_name': TextField(analyzer='foo')
}
)

instance = NonCallableMock(
person=NonCallableMock(first_name='foo', last_name='bar')
)

self.assertEqual(field.get_value_from_instance(instance), {
'first_name': "foo"
})

def test_get_value_from_instance_without_properties(self):
field = ObjectField(attr='person')

instance = NonCallableMock(
person={'first_name': 'foo', 'last_name': 'bar'}
)

self.assertEqual(field.get_value_from_instance(instance),
{
'first_name': "foo",
'last_name': "bar"
}
)

def test_get_value_from_instance_with_inner_objectfield(self):
field = ObjectField(attr='person', properties={
'first_name': TextField(analyzier='foo'),
Expand All @@ -120,6 +150,30 @@ def test_get_value_from_instance_with_inner_objectfield(self):
'aditional': {'age': 12}
})

def test_get_value_from_instance_with_inner_objectfield_without_properties(self):
field = ObjectField(
attr='person',
properties={
'first_name': TextField(analyzer='foo'),
'last_name': TextField(),
'additional': ObjectField()
}
)

instance = NonCallableMock(person=NonCallableMock(
first_name="foo",
last_name="bar",
additional={'age': 12}
))

self.assertEqual(field.get_value_from_instance(instance),
{
'first_name': "foo",
'last_name': "bar",
'additional': {'age': 12}
}
)

def test_get_value_from_instance_with_none_inner_objectfield(self):
field = ObjectField(attr='person', properties={
'first_name': TextField(analyzier='foo'),
Expand Down Expand Up @@ -168,6 +222,29 @@ def test_get_value_from_iterable(self):
}
])

def test_get_value_from_iterable_without_properties(self):
field = ObjectField(attr='person')

instance = NonCallableMock(
person=[
{'first_name': "foo1", 'last_name': "bar1"},
{'first_name': "foo2", 'last_name': "bar2"}
]
)

self.assertEqual(field.get_value_from_instance(instance),
[
{
'first_name': "foo1",
'last_name': "bar1",
},
{
'first_name': "foo2",
'last_name': "bar2",
}
]
)


class NestedFieldTestCase(TestCase):
def test_get_mapping(self):
Expand Down