Skip to main content

Algolia Search integration for Django

Project description

Algolia for Django

The perfect starting point to integrate Algolia within your Django project

Build Status Coverage Status PyPi Version

DocumentationCommunity ForumStack OverflowReport a bugFAQSupport

API Documentation

You can find the full reference on Algolia's website.

  1. Setup

  2. Commands

  3. Search

  4. Geo-Search

  5. Tags

  6. Options

  7. Tests

  8. Troubleshooting

Setup

Introduction

This package lets you easily integrate the Algolia Search API to your Django project. It's based on the 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.

  • Compatible with Python 3.8+.
  • Supports Django 4.x and 5.x.

Install

pip install algoliasearch-django

Setup

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

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

There are several optional settings:

  • INDEX_PREFIX: prefix all indices. Use it to separate different applications, like site1_Products and site2_Products.
  • INDEX_SUFFIX: suffix all indices. 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

Create an index.py inside each application that contains the models you want to index. Inside this file, call algoliasearch.register() for each of the models you want to index:

# index.py

import algoliasearch_django as algoliasearch

from .models import YourModel

algoliasearch.register(YourModel)

By default, all the fields of your model will be used. You can configure the index by creating a subclass of AlgoliaIndex and using the register decorator:

# index.py

from algoliasearch_django import AlgoliaIndex
from algoliasearch_django.decorators import register

from .models import YourModel

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

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 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.

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).

class Contact(models.model):
    name = models.CharField(max_length=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.

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.

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.

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's attribute, you need to define proxy methods for these fields.

Models

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

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.

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.

class Contact(models.model):
    name = models.CharField(max_length=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:
from algoliasearch_django import AlgoliaIndex

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

class MyModelIndex2(AlgoliaIndex):
    name = 'MyModelIndex2'
    ...
  • Then, define a meta model which will aggregate those indices:
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_objects(self):
        for index in self.indices:
            index.clear_objects()

    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:
import algoliasearch_django as algoliasearch
algoliasearch.register(MyModel, MyModelMetaIndex)

Temporarily disable the auto-indexing

It is possible to temporarily disable the auto-indexing feature using the disable_auto_indexing context decorator:

from algoliasearch_django.decorators import disable_auto_indexing

# Used as a context manager
with disable_auto_indexing():
    MyModel.save()

# Used as a decorator
@disable_auto_indexing():
my_method()

# You can also specifiy for which model you want to disable the auto-indexing
with disable_auto_indexing(MyModel):
    MyModel.save()
    MyOtherModel.save()

Tests

Run Tests

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

ALGOLIA_APPLICATION_ID={APPLICATION_ID} ALGOLIA_API_KEY={ADMIN_API_KEY} tox

To override settings for some tests, use the settings method:

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():
        # ...

Troubleshooting

Use the Dockerfile

If you want to contribute to this project without installing all its dependencies, you can use our Docker image. Please check our dedicated guide to learn more.

Frequently asked questions

Encountering an issue? Before reaching out to support, we recommend heading to our FAQ where you will find answers for the most common issues and gotchas with the package.

Project details


Download files

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

Source Distribution

algoliasearch_django-4.0.0.tar.gz (26.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

algoliasearch_django-4.0.0-py2.py3-none-any.whl (18.7 kB view details)

Uploaded Python 2Python 3

File details

Details for the file algoliasearch_django-4.0.0.tar.gz.

File metadata

  • Download URL: algoliasearch_django-4.0.0.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for algoliasearch_django-4.0.0.tar.gz
Algorithm Hash digest
SHA256 c0acb8231163c16757d9e4c37a0ce882b89c4640a6dc836daaf479fd73c427b5
MD5 acf4dc73373126f1a84f10274905110e
BLAKE2b-256 f1b630682918e1d7a82b4b5d1c1c257b80edf4165f7b49c01c2f7d63a10968c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for algoliasearch_django-4.0.0.tar.gz:

Publisher: main.yml on algolia/algoliasearch-django

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file algoliasearch_django-4.0.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for algoliasearch_django-4.0.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 d160b86cd999607e9b3b0773a712e196e251af2b7dcb2480e40ef09440f3c80a
MD5 c218935ae49d06fc184563e7625366b8
BLAKE2b-256 3d7df6caf0d2ed954f6db40a1179be8cd7a5d03611aa6d6fb6056e1889714599

See more details on using hashes here.

Provenance

The following attestation bundles were made for algoliasearch_django-4.0.0-py2.py3-none-any.whl:

Publisher: main.yml on algolia/algoliasearch-django

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page