Skip to main content

Algolia Search integration for Django

Project description


# Algolia Search API Client for Django

[Algolia Search](https://www.algolia.com) is a hosted full-text, numerical,
and faceted search engine capable of delivering realtime results from the first keystroke.

[![Build Status](https://travis-ci.org/algolia/algoliasearch-django.svg?branch=master)](https://travis-ci.org/algolia/algoliasearch-django)
[![Coverage Status](https://coveralls.io/repos/algolia/algoliasearch-django/badge.svg?branch=master)](https://coveralls.io/r/algolia/algoliasearch-django)
[![PyPI version](https://badge.fury.io/py/algoliasearch-django.svg?branch=master)](http://badge.fury.io/py/algoliasearch-django)


This package lets you easily integrate the Algolia Search API to your [Django](https://www.djangoproject.com/) project. It's based on the [algoliasearch-client-python](https://github.com/algolia/algoliasearch-client-python) package.

You might be interested in this sample Django application providing a typeahead.js based auto-completion and Google-like instant search: [algoliasearch-django-example](https://github.com/algolia/algoliasearch-django-example)

Compatible with **Python 2.7**, **Python 3.3+** and **Django 1.7+**



## API Documentation

You can find the full reference on [Algolia's website](https://www.algolia.com/doc/api-client/django/).



1. **[Setup](#setup)**
* [Introduction](#introduction)
* [Install](#install)
* [Setup](#setup)
* [Quick Start](#quick-start)

1. **[Commands](#commands)**
* [Commands](#commands)

1. **[Search](#search)**
* [Search](#search)

1. **[Geo-Search](#geo-search)**
* [Geo-Search](#geo-search)

1. **[Tags](#tags)**
* [Tags](#tags)

1. **[Options](#options)**
* [Custom <code>objectID</code>](#custom-codeobjectidcode)
* [Custom index name](#custom-index-name)
* [Field Preprocessing and Related objects](#field-preprocessing-and-related-objects)
* [Index settings](#index-settings)
* [Restrict indexing to a subset of your data](#restrict-indexing-to-a-subset-of-your-data)
* [Multiple indices per model](#multiple-indices-per-model)

1. **[Tests](#tests)**
* [Run Tests](#run-tests)





# Setup



## Introduction

This package lets you easily integrate the Algolia Search API to your [Django](https://www.djangoproject.com/) project. It's based on the [algoliasearch-client-python](https://github.com/algolia/algoliasearch-client-python) package.

You might be interested in this sample Django application providing a typeahead.js based auto-completion and Google-like instant search: [algoliasearch-django-example](https://github.com/algolia/algoliasearch-django-example)

Compatible with **Python 2.7**, **Python 3.3+** and **Django 1.7+**

## Install

```sh
pip install algoliasearch-django
```

## Setup

In your Django settings, add `algoliasearch_django` to `INSTALLED_APPS` and add these two settings:

```python
ALGOLIA = {
'APPLICATION_ID': 'MyAppID',
'API_KEY': 'MyApiKey'
}
```

There are several optional settings:

* `INDEX_PREFIX`: prefix all indexes. Use it to separate different applications, like `site1_Products` and `site2_Products`.
* `INDEX_SUFFIX`: suffix all indexes. Use it to differentiate development and production environments, like `Location_dev` and `Location_prod`.
* `AUTO_INDEXING`: automatically synchronize the models with Algolia (default to **True**).
* `RAISE_EXCEPTIONS`: raise exceptions on network errors instead of logging them (default to **settings.DEBUG**).

## Quick Start

Simply call `algoliasearch.register()` for each of the models you want to index. A good place to do this is in your application's AppConfig (generally named `apps.py`). More info in the [documentation](https://docs.djangoproject.com/en/1.8/ref/applications/)

```python
from django.apps import AppConfig
import algoliasearch_django as algoliasearch

class YourAppConfig(AppConfig):
name = 'your_app'

def ready(self):
YourModel = self.get_model('your_model')
algoliasearch.register(YourModel)
```

And then, don't forget the line below in the `__init__.py` file of your Django application.

```python
default_app_config = 'your_django_app.apps.YourAppConfig'
```

By default, all the fields of your model will be used. You can configure the index by creating a subclass of `AlgoliaIndex`. A good place to do this is in a separate file, like `index.py`.

```python
from algoliasearch_django import AlgoliaIndex

class YourModelIndex(AlgoliaIndex):
fields = ('name', 'date')
geo_field = 'location'
settings = {'searchableAttributes': ['name']}
index_name = 'my_index'
```

And then replace `algoliasearch.register(YourModel)` with `algoliasearch.register(YourModel, YourModelIndex)`.




# Commands



## Commands

* `python manage.py algolia_reindex`: reindex all the registered models. This command will first send all the record to a temporary index and then moves it.
* you can pass ``--model`` parameter to reindex a given model
* `python manage.py algolia_applysettings`: (re)apply the index settings.
* `python manage.py algolia_clearindex`: clear the index




# Search



## Search

We recommend using our [InstantSearch.js library](https://community.algolia.com/instantsearch.js) to build your search
interface and perform search queries directly from the end-user browser without going through your server.

However, if you want to search from your backend you can use the `raw_search(YourModel, 'yourQuery', params)` method.
It retrieves the raw JSON answer from the API, and accepts in `param` any
[search parameters](https://www.algolia.com/doc/api-reference/search-api-parameters/).

```python
from algoliasearch_django import raw_search

params = { "hitsPerPage": 5 }
response = raw_search(Contact, "jim", params)
```




# Geo-Search



## Geo-Search

Use the `geo_field` attribute to localize your record. `geo_field` should be a callable that returns a tuple (latitude, longitude).

```python
class Contact(models.model):
name = models.CharField(max_lenght=20)
lat = models.FloatField()
lng = models.FloatField()

def location(self):
return (self.lat, self.lng)

class ContactIndex(AlgoliaIndex):
fields = 'name'
geo_field = 'location'

algoliasearch.register(Contact, ContactIndex)
```




# Tags



## Tags

Use the `tags` attributes to add tags to your record. It can be a field or a callable.

```python
class ArticleIndex(AlgoliaIndex):
tags = 'category'
```

At query time, specify `{ tagFilters: 'tagvalue' }` or `{ tagFilters: ['tagvalue1', 'tagvalue2'] }` as search parameters to restrict the result set to specific tags.




# Options



## Custom `objectID`

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.

```python
class ArticleIndex(AlgoliaIndex):
custom_objectID = 'post_id'
```

## Custom index name

You can customize the index name. By default, the index name will be the name of the model class.

```python
class ContactIndex(algoliaindex):
index_name = 'Enterprise'
```

## Field Preprocessing and Related objects

If you want to process a field before indexing it (e.g. capitalizing a `Contact`'s `name`),
or if you want to index a [related object](https://docs.djangoproject.com/en/1.11/ref/models/relations/)'s
attribute, you need to define **proxy methods** for these fields.

### Models

```python
class Account(models.Model):
username = models.CharField(max_length=40)
service = models.CharField(max_length=40)

class Contact(models.Model):
name = models.CharField(max_length=40)
email = models.EmailField(max_length=60)
//...
accounts = models.ManyToManyField(Account)

def account_names(self):
return [str(account) for account in self.accounts.all()]

def account_ids(self):
return [account.id for account in self.accounts.all()]
```

### Index

```python
from algoliasearch_django import AlgoliaIndex

class ContactIndex(AlgoliaIndex):
fields = ('name', 'email', 'company', 'address', 'city', 'county',
'state', 'zip_code', 'phone', 'fax', 'web', 'followers', 'account_names', 'account_ids')

settings = {
'searchableAttributes': ['name', 'email', 'company', 'city', 'county', 'account_names',
}
```

- With this configuration, you can search for a `Contact` using its `Account` names
- You can use the associated `account_ids` at search-time to fetch more data from your
model (you should **only proxy the fields relevant for search** to keep your records' size
as small as possible)

## Index settings

We provide many ways to configure your index allowing you to tune your overall index relevancy.
All the configuration is explained on [our doc](https://www.algolia.com/doc/api-reference/api-parameters/).

```python
class ArticleIndex(AlgoliaIndex):
settings = {
'searchableAttributes': ['name', 'description', 'url'],
'customRanking': ['desc(vote_count)', 'asc(name)']
}
```

## Restrict indexing to a subset of your data

You can add constraints controlling if a record must be indexed or not. `should_index` should be a
callable that returns a boolean.

```python
class Contact(models.model):
name = models.CharField(max_lenght=20)
age = models.IntegerField()

def is_adult(self):
return (self.age >= 18)

class ContactIndex(AlgoliaIndex):
should_index = 'is_adult'
```

## Multiple indices per model

It is possible to have several indices for a single model.

- First, define all your indices that you want for a model:

```python
from django.contrib.algoliasearch import AlgoliaIndex

class MyModelIndex1(AlgoliaIndex):
name = 'MyModelIndex1'
...

class MyModelIndex2(AlgoliaIndex):
name = 'MyModelIndex2'
...
```

- Then, define a meta model which will aggregate those indices:

```python
class MyModelMetaIndex(AlgoliaIndex):
def __init__(self, model, client, settings):
self.indices = [
MyModelIndex1(model, client, settings),
MyModelIndex2(model, client, settings),
]

def raw_search(self, query='', params=None):
res = {}
for index in self.indices:
res[index.name] = index.raw_search(query, params)
return res

def update_records(self, qs, batch_size=1000, **kwargs):
for index in self.indices:
index.update_records(qs, batch_size, **kwargs)

def reindex_all(self, batch_size=1000):
for index in self.indices:
index.reindex_all(batch_size)

def set_settings(self):
for index in self.indices:
index.set_settings()

def clear_index(self):
for index in self.indices:
index.clear_index()

def save_record(self, instance, update_fields=None, **kwargs):
for index in self.indices:
index.save_record(instance, update_fields, **kwargs)

def delete_record(self, instance):
for index in self.indices:
index.delete_record(instance)
```

- Finally, register this `AlgoliaIndex` with your `Model`:

```python
import algoliasearch_django as algoliasearch
algoliasearch.register(MyModel, MyModelMetaIndex)
```




# Tests



## Run Tests

To run the tests, first find your Algolia application id and Admin API key (found on the Credentials page).

```shell
ALGOLIA_APPLICATION_ID={APPLICATION_ID} ALGOLIA_API_KEY={ADMIN_API_KEY} tox
```


To override settings for some tests, use the [settings method](https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.SimpleTestCase.settings):
```python
class OverrideSettingsTestCase(TestCase):
def setUp(self):
with self.settings(ALGOLIA={
'APPLICATION_ID': 'foo',
'API_KEY': 'bar',
'AUTO_INDEXING': False
}):
algolia_engine.reset(settings.ALGOLIA)

def tearDown(self):
algolia_engine.reset(settings.ALGOLIA)

def test_foo():
# ...
```





Project details


Release history Release notifications

This version
History Node

1.5.6

History Node

1.5.5

History Node

1.5.4

History Node

1.5.2

History Node

1.5.1

History Node

1.5.0

History Node

1.4.1

History Node

1.4.0

History Node

1.3.2

History Node

1.3.1

History Node

1.3.0

History Node

1.2.5

History Node

1.2.4

History Node

1.2.3

History Node

1.2.2

History Node

1.2.1

History Node

1.2.0

History Node

1.1.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
algoliasearch_django-1.5.6-py2.py3-none-any.whl (15.7 kB) Copy SHA256 hash SHA256 Wheel py2.py3 May 15, 2018
algoliasearch-django-1.5.6.tar.gz (14.6 kB) Copy SHA256 hash SHA256 Source None May 15, 2018

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging CloudAMQP CloudAMQP RabbitMQ AWS AWS Cloud computing Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page