Skip to content

Commit ae97986

Browse files
committed
Add tags capaciy, close #5
1 parent a4451c1 commit ae97986

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed

README.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,44 +98,55 @@ We recommend the usage of our [JavaScript API Client](https://github.com/algolia
9898

9999
## Geo-Search
100100

101-
Use the `geo_field` attribute to localize your record. `geo_field` can be a tuple or a callable that return a tuple (latitude, longitude).
101+
Use the `geo_field` attribute to localize your record. `geo_field` should be a callable that returns a tuple (latitude, longitude).
102102

103103
```python
104-
class Contact(models.Model):
105-
name = models.CharField()
106-
lat = models.FloatField()
107-
lng = models.FloatField()
104+
class contact(models.model):
105+
name = models.charfield()
106+
lat = models.floatfield()
107+
lng = models.floatfield()
108108

109109
def location(self):
110110
return (self.lat, self.lng)
111111

112112

113-
class ContactIndex(AlgoliaIndex):
113+
class contactindex(algoliaindex):
114114
fields = 'name'
115115
geo_field = 'location'
116116

117117

118-
algoliasearch.register(Contact, ContactIndex)
118+
algoliasearch.register(contact, contactindex)
119119
```
120120

121-
# Options
121+
# Tags
122122

123-
## Custom `objectID`
124-
125-
You can choose which field will be used as the `objectID`. The field should be unique and can be a string or integer. By default, we use the `pk` field of the model.
123+
Use the `tags` attributes to add tags to your record. It can be a field or a callable.
126124

127125
```python
128126
class ArticleIndex(AlgoliaIndex):
129-
custom_objectID = 'post_id'
127+
tags = 'category'
128+
```
129+
130+
At query time, specify `{ tagFilters: 'tagvalue' }` or `{ tagFilters: ['tagvalue1', 'tagvalue2'] }` as search parameters to restrict the result set to specific tags.
131+
132+
# options
133+
134+
## custom `objectid`
135+
136+
you can choose which field will be used as the `objectid`. the field should be unique and can be a string or integer. by default, we use the `pk` field of the model.
137+
138+
```python
139+
class articleindex(algoliaindex):
140+
custom_objectid = 'post_id'
130141
```
131142

132-
## Custom index name
143+
## custom index name
133144

134-
You can customize the inde name. By default, the index name will be the name of the model class.
145+
You can customize the index name. By default, the index name will be the name of the model class.
135146

136147
```python
137-
class ContactIndex(AlgoliaIndex):
138-
index_name = 'Entreprise'
148+
class contactindex(algoliaindex):
149+
index_name = 'entreprise'
139150
```
140151

141152
## Index settings

src/models.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ class AlgoliaIndex(object):
2525
fields = ()
2626

2727
# Use to specify the geo-fields that should be used for location search.
28-
# The field should be a tuple or a callable that returns a tuple.
28+
# The field should be a callable that returns a tuple.
2929
geo_field = None
3030

31+
# Use to specify the field that should be used for filtering by tag.
32+
tags = None
33+
3134
# Use to specify the index to target on Algolia.
3235
index_name = None
3336

@@ -60,19 +63,30 @@ def __init__(self, model, client):
6063
self.fields = all_fields
6164
self.fields.remove('id')
6265

63-
# Check geo_field
64-
if self.geo_field:
65-
if not hasattr(model, self.geo_field):
66-
raise AlgoliaIndexError('{} is not an attribute of {}.'.format(
67-
self.geo_field, model))
68-
6966
# Check custom_objectID
7067
if self.custom_objectID:
7168
if not (hasattr(model, self.custom_objectID) or
7269
(self.custom_objectID in all_fields)):
7370
raise AlgoliaIndex('{} is not an attribute of {}.'.format(
7471
self.custom_objectID, model))
7572

73+
# Check tags
74+
if self.tags:
75+
if not (hasattr(model, self.tags) or (self.tags in all_fields)):
76+
raise AlgoliaIndex('{} is not an attribute of {}'.format(
77+
self.tags, model))
78+
79+
# Check geo_field
80+
if self.geo_field:
81+
if hasattr(model, self.geo_field):
82+
attr = getattr(model, self.geo_field)
83+
if not callable(attr):
84+
raise AlgoliaIndexError('{} should be a callable.'.format(
85+
self.geo_field))
86+
else:
87+
raise AlgoliaIndexError('{} is not an attribute of {}.'.format(
88+
self.geo_field, model))
89+
7690
def __set_index(self, client):
7791
'''Get an instance of Algolia Index'''
7892
params = getattr(settings, 'ALGOLIA', None)
@@ -98,11 +112,14 @@ def __set_index(self, client):
98112
def __get_objectID(self, instance):
99113
'''Return the objectID of an instance.'''
100114
if self.custom_objectID:
101-
return getattr(instance, self.custom_objectID)
115+
attr = getattr(instance, self.custom_objectID)
116+
if callable(attr):
117+
attr = attr()
118+
return attr
102119
else:
103120
return instance.pk
104121

105-
def __build_object(self, instance):
122+
def _build_object(self, instance):
106123
'''Build the JSON object.'''
107124
tmp = {'objectID': self.__get_objectID(instance)}
108125
if isinstance(self.fields, dict):
@@ -123,12 +140,21 @@ def __build_object(self, instance):
123140
if callable(attr):
124141
attr = attr()
125142
tmp['_geoloc'] = {'lat': attr[0], 'lng': attr[1]}
143+
144+
if self.tags:
145+
attr = getattr(instance, self.tags)
146+
if callable(attr):
147+
attr = attr()
148+
if not isinstance(attr, list):
149+
attr = list(attr)
150+
tmp['_tags'] = attr
151+
126152
logger.debug('BUILD %s FROM %s', tmp['objectID'], self.model)
127153
return tmp
128154

129155
def update_obj_index(self, instance):
130156
'''Update the object.'''
131-
obj = self.__build_object(instance)
157+
obj = self._build_object(instance)
132158
self.__index.save_object(obj)
133159
logger.debug('UPDATE %s FROM %s', obj['objectID'], self.model)
134160

@@ -161,7 +187,7 @@ def reindex_all(self, batch_size=1000):
161187
counts = 0
162188
batch = []
163189
for instance in self.model.objects.all():
164-
batch.append(self.__build_object(instance))
190+
batch.append(self._build_object(instance))
165191
if len(batch) >= batch_size:
166192
result = self.__tmp_index.save_objects(batch)
167193
logger.info('SAVE %d OBJECTS TO %s_tmp', len(batch),

tests/test_index.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,23 @@ class ExampleIndex(AlgoliaIndex):
4141
geo_field = 'location'
4242

4343
index = ExampleIndex(Example, self.client)
44-
obj = index._AlgoliaIndex__build_object(self.instance)
44+
obj = index._build_object(self.instance)
4545
self.assertEqual(obj['_geoloc'], {'lat': 63.3, 'lng': -32.0})
4646

4747
def test_custom_objectID(self):
4848
class ExampleIndex(AlgoliaIndex):
4949
custom_objectID = 'uid'
5050

5151
index = ExampleIndex(Example, self.client)
52-
obj = index._AlgoliaIndex__build_object(self.instance)
52+
obj = index._build_object(self.instance)
5353
self.assertEqual(obj['objectID'], 4)
5454

5555
def test_one_field(self):
5656
class ExampleIndex(AlgoliaIndex):
5757
fields = 'name'
5858

5959
index = ExampleIndex(Example, self.client)
60-
obj = index._AlgoliaIndex__build_object(self.instance)
60+
obj = index._build_object(self.instance)
6161
self.assertNotIn('uid', obj)
6262
self.assertIn('name', obj)
6363
self.assertNotIn('address', obj)
@@ -71,7 +71,7 @@ class ExampleIndex(AlgoliaIndex):
7171
fields = ('name', 'address')
7272

7373
index = ExampleIndex(Example, self.client)
74-
obj = index._AlgoliaIndex__build_object(self.instance)
74+
obj = index._build_object(self.instance)
7575
self.assertNotIn('uid', obj)
7676
self.assertIn('name', obj)
7777
self.assertIn('address', obj)

0 commit comments

Comments
 (0)