@@ -38,6 +38,8 @@ class AlgoliaIndex(object):
38
38
# - a BooleanField
39
39
# - a boolean property or attribute
40
40
should_index = None
41
+ # Name of the attribute to check on instances if should_index is not a callable
42
+ _should_index_is_method = False
41
43
42
44
# Instance of the index from algoliasearch client
43
45
__index = None
@@ -94,23 +96,20 @@ def __init__(self, model, client):
94
96
raise AlgoliaIndexError ('{} is not an attribute of {}.' .format (
95
97
self .geo_field , model ))
96
98
97
- # Check should_index + get the callable
99
+ # Check should_index + get the callable or attribute/field name
98
100
if self .should_index :
99
101
if hasattr (model , self .should_index ):
100
102
attr = getattr (model , self .should_index )
101
- if callable (attr ):
103
+ if type (attr ) is not bool : # if attr is a bool, we keep attr=name to getattr on instance
102
104
self .should_index = attr
103
- else :
104
- should_index_attr_name = self .should_index
105
- if isinstance (attr , bool ):
106
- self .should_index = lambda instance : getattr (instance , should_index_attr_name ) is True
107
- self .should_index ._is_default = True
108
- else :
109
- raise AlgoliaIndexError ('{} should be a bound callable or a boolean attribute.' .format (
110
- self .should_index ))
105
+ if callable (self .should_index ):
106
+ self ._should_index_is_method = True
111
107
else :
112
- raise AlgoliaIndexError ('{} is not an attribute of {}.' .format (
113
- self .should_index , model ))
108
+ try :
109
+ model ._meta .get_field_by_name (self .should_index )
110
+ except :
111
+ raise AlgoliaIndexError ('{} is not an attribute nor a field of {}.' .format (
112
+ self .should_index , model ))
114
113
115
114
def __set_index (self , client ):
116
115
'''Get an instance of Algolia Index'''
@@ -196,8 +195,8 @@ def _build_object(self, instance):
196
195
return tmp
197
196
198
197
def update_obj_index (self , instance ):
199
- ''' Update the object.'''
200
- if self .should_index :
198
+ """ Update the object."""
199
+ if self ._has_should_index () :
201
200
if not self ._should_really_index (instance ):
202
201
# Should not index, but since we don't now the state of the
203
202
# instance, we need to send a DELETE request to ensure that if
@@ -209,21 +208,40 @@ def update_obj_index(self, instance):
209
208
self .__index .save_object (obj )
210
209
logger .debug ('UPDATE %s FROM %s' , obj ['objectID' ], self .model )
211
210
211
+ def _has_should_index (self ):
212
+ """Return True if this AlgoliaIndex has a should_index method or attribute"""
213
+ return self .should_index is not None
214
+
212
215
def _should_index (self , instance ):
213
- """Return true if the object should be indexed (including when self.should_index is not set)."""
214
- if self .should_index :
216
+ """Return True if the object should be indexed (including when self.should_index is not set)."""
217
+ if self ._has_should_index () :
215
218
return self ._should_really_index (instance )
216
219
else :
217
220
return True
218
221
219
222
def _should_really_index (self , instance ):
220
- """Return true if according to should_index the object should be indexed."""
221
- if hasattr (self .should_index , "__self__" ) or hasattr (self .should_index , '_is_default' ):
222
- # bound method or lambda, let's use instance
223
- return self .should_index (instance )
223
+ """Return True if according to should_index the object should be indexed."""
224
+ if self ._should_index_is_method :
225
+ if hasattr (self .should_index , "__self__" ):
226
+ # bound method, call with instance
227
+ return self .should_index (instance )
228
+ else :
229
+ # unbound method, simply call without arguments
230
+ return self .should_index ()
224
231
else :
225
- # unbound method, simply call without arguments
226
- return self .should_index ()
232
+ # property/attribute/Field, evaluate as bool
233
+ attr_type = type (self .should_index )
234
+ if attr_type is str :
235
+ attr_value = getattr (instance , self .should_index )
236
+ elif attr_type is property :
237
+ attr_value = self .should_index .__get__ (instance )
238
+ else :
239
+ raise AlgoliaIndexError ('{} should be a boolean attribute or a method that returns a boolean.' .format (
240
+ self .should_index ))
241
+ if type (attr_value ) is not bool :
242
+ raise AlgoliaIndexError ("%s's should_index (%s) should be a boolean" % (
243
+ instance .__class__ .__name__ , self .should_index ))
244
+ return attr_value
227
245
228
246
def delete_obj_index (self , instance ):
229
247
'''Delete the object.'''
0 commit comments