Skip to content

Commit 6470dd7

Browse files
Allow for ObjectFields to call prepare_func included in InnerDoc. (django-es#346)
* Allow for ObjectFields to call prepare_funcs from elasticsearch_dsl.InnerDoc * Minor cleanup for from PR review
1 parent b0aa174 commit 6470dd7

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

django_elasticsearch_dsl/fields.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,16 @@ def _get_inner_field_data(self, obj, field_value_to_ignore=None):
115115
if field._path == []:
116116
field._path = [name]
117117

118-
data[name] = field.get_value_from_instance(
119-
obj, field_value_to_ignore
120-
)
118+
# This allows for retrieving data from an InnerDoc with prepare_field_name functions.
119+
doc_instance = self._doc_class()
120+
prep_func = getattr(doc_instance, 'prepare_%s' % name, None)
121+
122+
if prep_func:
123+
data[name] = prep_func(obj)
124+
else:
125+
data[name] = field.get_value_from_instance(
126+
obj, field_value_to_ignore
127+
)
121128

122129
# This allows for ObjectFields to be indexed from dicts with
123130
# dynamic keys (i.e. keys/fields not defined in 'properties')

tests/test_documents.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from django.db import models
55
from django.utils.translation import ugettext_lazy as _
6-
from elasticsearch_dsl import GeoPoint, MetaField
6+
from elasticsearch_dsl import GeoPoint, MetaField, InnerDoc
77
from mock import patch, Mock, PropertyMock
88

99
from django_elasticsearch_dsl import fields
@@ -173,6 +173,43 @@ def test_prepare(self):
173173
}
174174
)
175175

176+
def test_innerdoc_prepare(self):
177+
class ManufacturerInnerDoc(InnerDoc):
178+
name = fields.TextField()
179+
location = fields.TextField()
180+
181+
def prepare_location(self, instance):
182+
return "USA"
183+
184+
@registry.register_document
185+
class CarDocumentWithInnerDoc(DocType):
186+
manufacturer = fields.ObjectField(doc_class=ManufacturerInnerDoc)
187+
188+
class Django:
189+
model = Car
190+
fields = ['name', 'price']
191+
192+
class Index:
193+
name = 'car_index'
194+
195+
manufacturer = Manufacturer(
196+
name="Bugatti",
197+
)
198+
199+
car = Car(name="Type 57", price=5400000.0, manufacturer=manufacturer)
200+
doc = CarDocumentWithInnerDoc()
201+
prepared_data = doc.prepare(car)
202+
self.assertEqual(
203+
prepared_data, {
204+
'name': car.name,
205+
'price': car.price,
206+
'manufacturer': {
207+
'name': car.manufacturer.name,
208+
'location': ManufacturerInnerDoc().prepare_location(manufacturer)
209+
}
210+
}
211+
)
212+
176213
def test_prepare_ignore_dsl_base_field(self):
177214
@registry.register_document
178215
class CarDocumentDSlBaseField(DocType):

0 commit comments

Comments
 (0)