Git Product home page Git Product logo

algoliasearch-django's Introduction

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 2.7 and Python 3.4+.
  • Supports Django 1.7+, 2.x and 3.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_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:
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.

algoliasearch-django's People

Contributors

adamghill avatar algolia-bot avatar algoliareadmebot avatar arnaudlimbourg avatar aseure avatar chloelbn avatar clemfromspace avatar dethi avatar fourfridays avatar jensenbox avatar julienbourdeau avatar leoercolanelli avatar nunomaduro avatar plnech avatar qcaron avatar redox avatar sanyambansal76 avatar sarahdayan avatar shortcuts avatar stuross avatar sxalexander avatar tkrugg avatar usamasadiq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

algoliasearch-django's Issues

Feature request: Support distinct option for de-duplication

Description

Documentation: https://www.algolia.com/doc/guides/ranking/distinct/#distinct-for-de-duplication

I am hitting the 10kb limit for records and I need to be able to support de-duplication. Here is my use case:

  • I have one model that contains a list of locations
  • for some models, this list contains a lot of locations (some thousands)
  • when indexing my model, I want to push 1 record for each location in the list: this will tremendously decrease record size while at the same time enhance the search experience

Are you willing to accept PRs for this feature? I can draft a spec here and get on with it 💪
Cheers!

Error when unicode_literals is used

Hello,

When using from __future__ import unicode_literals on a custom index.pyfile the indexing breaks.

As far as I can see this is because https://github.com/algolia/algoliasearch-django/blob/master/algoliasearch_django/models.py#L96 expect an str instance whereas unicode_literals makes it a unicode one.

I have removed the unicode_literals for now as I have not looked if there are other places that would be impacted.

It looks like adding an extra check for unicode would be sufficient but I am not sure and would welcome any feedback.

ManyToMany field is not updated correctly

From a customer's e-mail:

Context

My project has a kind of scenario where my Django app has a model called Package and another called Author. My Package model on Django is structured so that it has a ManyToMany relation field with the Author model, so that one Package can have many Authors.

As I want to store the list of the Authors names on every Package record, I've made a method authors_names of the Package model class, that returns the list of Authors related to a Package ( simply like return list(self.authors.values_list('full_name', flat=True))), and so then I've put it on my fields list attribute of the class for the Algolia's Package Index.

In the Index fields list I've got other values related to my Package model, both 'direct' fields and others callable methods.
So, using the 'algolia_reindex' as shown here brings every Package objects I've got on my Django database to Algolia.

Problem

The problem I've encountered, comes to the update of objects in Django:

  1. Go to a page of an existing Package object on the Django admin, make some edits to fields and for example add an author on the many to many Author field of the Package, then save
  2. The post_save signal of Algolia is called to update the data on Algolia, but the record is not correctly updated: every edited 'direct' field of the Package is correctly updated, but the 'callable' fields referrer of a method of the Package class are updated before the Package's save itself, so their update is done using the old data (in the example I don't see on the updated Algolia record the newly added Author name on the list for the Package record just edited).

So the fields listed with the 'direct' field name string are always handled correctly, but briefly the problem is that the fields indicated on the Index with a string that refer to the name of a model method, are not updated correctly on Algolia when the objects of the related model are updated on the Django database.

Potential solution

I think that the reason is that the Algolia client for Django hooks the objects update on the post_save signal of Django, but this doesn't work with the cases I've described last time, so to work, it should be hooked after the transaction is completed (after the commit), so instead of the post_save signal the implementation should be a pre_save signal that calls transaction.on_commit and then update the object on Algolia.

Add support for non-callable for should_index attribute

Hi there,

I think it would be more convenient to handle both callable and non-callable attributes on the model instance. For example, I have a model field that is a boolean and I would like to use its value for the should_index parameter. I think it wouldn't be too hard too do. Would you be open to the idea?

(Note: this can be done easily for the should_index parameter, and given your AlgoliaIndex class design it shouldn't be too hard to have this for all parameters 🎉)

Edit: I just saw that you already support non-callable attributes here, so this issue only concerns should_index

python manage.py algolia_reindex - Killed

Hi, I'm having some trouble indexing.

python manage.py algolia_applysettings
Apply settings to index:
	* Product

python manage.py algolia_reindex:
The following models were reindexed:
Killed

Can someone please help me.

django-algolia project

Hi,

Since two months, I am working on a Django version of Algolia client.
His goal is simple: index (on the fly like haystack) the models that has a specified setting, allow to search by model and consume responses very easily.

class MyPony(models.Model):
  ALGOLIA_INDEX_FIELDS = ('name', 'clogs_number',)

  name = models.CharField(max_length=255)
  clogs_number = models.IntegerField()
./manage.py rebuild_algolia_index --model=MyPony
>>> import algolia
>>> from my.project.models import MyPony

>>> algolia.search(MyPony, 'Raibow')
AlgoliaResult({'count': 1, 'instances': [<MyPony: Rainbow Dash>], 'model': <class 'my.project.models.MyPony'>, 'page': '1/1'})

With a little bit of features like pagination, for work with Django Rest Framework.

import algolia
from algolia.pagination import Paginator as AlgoliaPaginator
from rest_framework import generics

class MyPonySearch(generics.ListAPIView):
    model = MyPony
    serializer_class = MyPonySerializer
    paginator_class = AlgoliaPaginator

    def get_queryset(self):
        return algolia.search(MyPony, self.requests.get('q', ''))

You can see all of that in the develop branch of my repo : https://github.com/Kmaschta/django-algolia/tree/develop
(the documentation is not up-to-date)

I learn with joy that you start to make an official Django lib!
But my work becomes obsolete, and work our separate ways is against-productive.

How can we ensure to collaborate about that?

register decorator gives TypeError

Hi guys,

I defined this index by following the instructions found in the documentation:

index.py

from algoliasearch_django import AlgoliaIndex, register

from .models import TestSearch


@register(TestSearch)
class TestSearchIndex(AlgoliaIndex):
    fields = (
        'text',
    )

Here are my models.py and settings.py for this test case:

models.py

from django.db import models

class TestSearch(models.Model):
    text = models.CharField(max_length=100)

    class Meta:
        verbose_name = 'Test'
        verbose_name_plural = 'Tests'

settings.py

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'content',
    'algoliasearch_django',
]
...
ALGOLIA = {
    'APPLICATION_ID': 'xxxxxxxx',
    'API_KEY': 'xxxxxxx',
    'INDEX_SUFFIX': 'dev',
}

I am getting this stacktrace when running ./manage.py algolia_applysettings:

(algolia_tests) quentins-mbp:algolia_tests quentincaron$ ./manage.py algolia_applysettings
Traceback (most recent call last):
  File "./manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/django/core/management/__init__.py", line 347, in execute
    django.setup()
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/django/apps/registry.py", line 120, in populate
    app_config.ready()
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/algoliasearch_django/apps.py", line 11, in ready
    self.module.autodiscover()
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/algoliasearch_django/__init__.py", line 46, in autodiscover
    autodiscover_modules('index')
  File "/Users/quentincaron/.virtualenvs/algolia_tests/lib/python3.6/site-packages/django/utils/module_loading.py", line 47, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/quentincaron/PycharmProjects/algolia_tests/content/index.py", line 7, in <module>
    class TestSearchIndex(AlgoliaIndex):
TypeError: 'NoneType' object is not callable

I am using:

  • Python 3.6.3
  • Django==2.0.6 (same with Django==1.11.13)
  • algoliasearch==1.17.0
  • algoliasearch-django==1.6.0

Is this a bug? If not, I can update the documentation based on your answers.

Using algoliasearch.register(YourModel) works except the settings.ALGOLIA.INDEX_SUFFIX is not taken into account and I need to customize my index as well.

Let me know if you need more about my issue.
Quentin

Allow specific models to be reindexed

  • Currently all models have to be synced everytime python manage.py algolia_reindex is called.
  • I would like to be able to make the following call: python manage.py algolia_reindex <MODEL_NAME> such that only the model passed will be reindexed with Algolia

Turning off Algolia for tests

How do we turn off algoliasearch-django for tests? The way signals are registered, and the registration of models to the engine in apps.py has been breaking our test suite--we need a simple way to turn Algolia indexing on and off within tests with just a simple setting.

Is there any way to do this? The only way I can see is the with self.settings(...) modification in the docs, which isn't simple but also doesn't seem to work when we tried it. We either get items indexing, or we get error issues that a model is already registered when we try to just remove the INSTALLED_APPS entirely.

By using the with self.settings(...) method and turning 'AUTO_INDEXING' to False, we're actually getting a RegistrationError that the model isn't registered with the Algolia engine now. I want Algolia code not to be firing at all during this test, so I'm not sure why this is happening.

Dynamic way to use multiple indexes per models

Hello there :)

Recently, I found myself in the needs to add multiple indexes per models, but in a dynamic way.

I used django-hvad for the model translations, and needed to "route" the models to a different index based on the language_code field of the model.

Do you know how if there is a way I could achieve this ?

When reindexing, the _tmp suffix can cause issues with index restricted keys

When reindexing, the code adds _tmp to the constructed index name:

def __init_index(self, client, model, settings):
if not self.index_name:
self.index_name = model.__name__
if 'INDEX_PREFIX' in settings:
self.index_name = settings['INDEX_PREFIX'] + '_' + self.index_name
if 'INDEX_SUFFIX' in settings:
self.index_name += '_' + settings['INDEX_SUFFIX']
self.__index = client.init_index(self.index_name)
self.__tmp_index = client.init_index(self.index_name + '_tmp')

Some users are using dedicated environment keys where there's an index restriction like "only for indexes named *_dev". Which mean that on reindexing the key won't be able to reindex because of the way we constructed the tmp index name.

Since we have very descriptive settings, I guess we could do something like this:

if prefix => tmp_index_name = index_name + tmp + env
if suffix => tmp_index_name = env + tmp + index_name

This should be sufficient?

Faster tests by using wait_task

Today, several of our tests are slowed down by forced sleeping:

def test_save_signal(self):
        Website.objects.create(name='Algolia', url='https://www.algolia.com')
        Website.objects.create(name='Google', url='https://www.google.com')
        Website.objects.create(name='Facebook', url='https://www.facebook.com')

        time.sleep(10)  # FIXME: Expose last task's ID so we can waitTask instead of sleeping
        self.assertEqual(raw_search(Website)['nbHits'], 3)

We could replace the sleep call by leveraging wait_task. This requires:

  • exposing it on the Client and not only on the index, see PR algolia/algoliasearch-client-python#343
  • facading it in AlgoliaEngine
  • Because the taskID is returned in the __post_save_receiver hook, we need to expose the last taskID somewhere like AlgoliaEngine.last_taskID so you can then refactor the previous code as:
def test_save_signal(self):
        Website.objects.create(name='Algolia', url='https://www.algolia.com')
        Website.objects.create(name='Google', url='https://www.google.com')
        Website.objects.create(name='Facebook', url='https://www.facebook.com')

        algolia_engine.wait_task(algolia_engine.last_taskID)
        self.assertEqual(raw_search(Website)['nbHits'], 3)

Line 68: helper.py - Python3.4 quote_from_bytes() expected bytes

Got unicode vs bytes error running the demo in python 3.4. Fix is below... Stack trace attached..

68 def safe(e):
"""Returns a safe string for URL."""
return quote(encode(e), safe='')

FIX
68 def safe(e):
"""Returns a safe string for URL."""
return quote(encode(str(e)), safe='')

manage.py loaddata contacts.json
Traceback (most recent call last):
File "manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/init.py", line 338, in execute_from_command_line
utility.execute()
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/init.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/base.py", line 393, in run_from_argv
self.execute(_args, *_cmd_options)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/base.py", line 444, in execute
output = self.handle(_args, *_options)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/commands/loaddata.py", line 60, in handle
self.loaddata(fixture_labels)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/commands/loaddata.py", line 90, in loaddata
self.load_label(fixture_label)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/management/commands/loaddata.py", line 147, in load_label
obj.save(using=self.using)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/core/serializers/base.py", line 173, in save
models.Model.save_base(self.object, using=using, raw=True)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/db/models/base.py", line 747, in save_base
update_fields=update_fields, raw=raw, using=using)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/dispatch/dispatcher.py", line 201, in send
response = receiver(signal=self, sender=sender, **named)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/contrib/algoliasearch/registration.py", line 126, in __post_save_receiver
self.update_obj_index(instance)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/contrib/algoliasearch/registration.py", line 110, in update_obj_index
adapter.update_obj_index(obj)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/django/contrib/algoliasearch/models.py", line 178, in update_obj_index
self.__index.save_object(obj)
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/algoliasearch/index.py", line 203, in save_object
path = '/%s' % safe(obj['objectID'])
File "/home/cypt/Dev/MiMP3/lib/python3.4/site-packages/algoliasearch/helpers.py", line 68, in safe
return quote(encode(e), safe='')
File "/usr/lib/python3.4/urllib/parse.py", line 694, in quote
return quote_from_bytes(string, safe)
File "/usr/lib/python3.4/urllib/parse.py", line 719, in quote_from_bytes
raise TypeError("quote_from_bytes() expected bytes")
TypeError: Problem installing fixture '/home/cypt/Dev/MiMP3/MiM/apps/algoliasearch-django-example/contacts.json': quote_from_bytes() expected bytes

Algolia prevents running or testing django offline

Running and testing locally is difficult when I have an unstable/no internet connection, yielding this exception:

algoliasearch.helpers.AlgoliaException: Unreachable hosts

There should be a mechanism to automatically swallow these errors. It seems these exceptions are run as warnings instead of exceptions in production, this behavior should be allowed to persist when DEBUG=True still if given a flag in settings or something.

I can make a pull request if that's something that makes sense

Line in question:

except AlgoliaException as e:
if DEBUG:
raise e
else:
logger.warning('%s FROM %s NOT SAVED: %s', obj['objectID'],
self.model, e)

support for setting_changed while testing

the AlgoliaEngine use the current settings at import time to build the «algolia_engine» global variable.

the problem is that while testing, we can require to stop the auto indexing for a given test with somthing like this :

    @override_settings(ALGOLIA={
        'APPLICATION_ID': 'bépo',
        'API_KEY': 'bépo',
        'AUTO_INDEXING': False
    })
    def test_extensive_function(self):
        assert somthing

in the current version, the override_settings has absolutly no effect and the client is not updated nor the post_save and post_delete signals is removed.

to use algoliasearch-django in some tests, i must do something like

from django.apps import AppConfig
from django.apps.registry import apps

class MyAppConfig(AppConfig):

    def reset_agolia_engin(self, *args, **kwargs):
        algolia_engine.unregister(apps.get_model('my_app', 'MyModel'))
        algolia_engine.__init__()  # reset client using new params
        algolia_engine.register(apps.get_model('my_app', 'MyModel'), MyModelIndex)

    def ready(self):
        setting_changed.connect(self.reset_agolia_engin)

Attribute Error When (Re)Indexing a Model

Hi,
This issue is similar to #13, but definitely distinct in my opinion.

I've followed the setup instructions for a model (User) in our application. Here is the definition for my Index class:

class UserAlgoliaIndex(AlgoliaIndex):
    # fields = ('username', 'email', 'first_name', 'last_name')
    settings = {'searchableAttributes': ['username', 'email',
                                         'first_name', 'last_name']}
    index_name = 'users'

When I uncomment the fields line, things work as expected. However, if I remove that line in an attempt to get all fields from the User model, I get the following exception:
AttributeError: 'User' object has no attribute 'logentry'.

I'm sure you know this ultimately stems from this line:
all_model_fields = [f.name for f in model._meta.get_fields()]
(89 in models.py).

For the sake of completeness, here is the result of that line for my User model:
['logentry', 'oauth2_provider_application', 'grant', 'accesstoken', 'refreshtoken', 'social_auth', 'userobjectpermission', 'notifications', 'notificationsettings', 'profile', 'emails', 'customer', 'projects', 'collaborator', 'projectfile', 'servers', 'actions', 'nodes', 'triggers', 'teams_created', 'groups_created', 'password', 'last_login', 'is_superuser', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'username', 'id', 'groups', 'user_permissions', 'team_groups'].

Of course logentry (and many others) is not an actual field on User, but instead a foreign key that references it. I'm not suggesting, or asking, that these relationships be traversed with a call to logentry_set.all() (I'm not even sure what it would mean to do so), but instead to just skip them altogether. In other words, change
all_model_fields = [f.name for f in model._meta.get_fields()] to
all_model_fields = [f.name for f in model._meta.get_fields() if not f.is_relation].

I have tested this change, and it seems to work. I know this can be worked around by manually defining the model fields I would like returned, but I do feel that this would lower the barrier of entry for using Algoliasearch with Django.

Perhaps there is a good reason for not doing it this way currently, or maybe I missed something in the documentation. If you feel this would be useful, I can certainly submit a PR.

Indexing a OneToOne User field only takes its username attribute

I have made two models Student and Teacher by extending Django's User Model in OneToOne fields student and teacher respectively. When i register my Student and Teacher models to algolia, it only takes the username attribute of User in student(or teacher). I am not able to access other fields of User model like first_name, last_name etc. in algolia. How can i access these fields?

Multiple models in same index won't work

I have decided to put all my models into one index and have added an attribute, modelname:

@property
def modelname(self):
    return self._meta.model_name

This works fine for automatic updates but using the management command I'm finding that the index is cleared between models regardless of whether I use a straight reindex or reindex --model as reindex clears the existing index first.

Is it possible to do a reindex without a clear first?

Bug: auto_indexing=False not taken into account when calling algoliasearch_django.register

  • Django version: 2.1.3
  • Algolia Django integration version: 1.7.0
  • Algolia Client Version: 1.17.0
  • Language Version: 3.6.6

Description

registration.py's register accepts an auto_indexing keyword (definition). Unfortunately, setting it to False has no effect as:

  • the AUTO_INDEXING setting is initially read; if it's absent, the internal variable __auto_indexing is set to a default of True
  • an incorrect check is made here: either the auto_indexing is a bool and its value is True OR self.__auto_indexing is True. Since self.__auto_indexing is True by default, passing auto_indexing=False to register does not do anything.

Steps To Reproduce

  • do not set the AUTO_INDEXING setting
  • use code similar to:
# index.py
from algoliasearch_django import register, AlgoliaIndex
from models import MyModel

class MyModelIndex(AlgoliaIndex):
  # ...

register(MyModel, MyModelIndex, auto_indexing=False)

# somewhere else
m = MyModel()
m.save()
# at this point, __post_save_receiver gets called

Install fails on pipenv 10.1.0

Davids-MacBook:barberscore-api dbinetti$ pipenv install algoliasearch-django
Installing algoliasearch-django…
⠋
Error:  An error occurred while installing algoliasearch-django!
Failed to import the site module
Traceback (most recent call last):
  File "/Users/dbinetti/repos/barberscore-api/.venv/bin/../lib/python3.6/site.py", line 703, in <module>
    main()
  File "/Users/dbinetti/repos/barberscore-api/.venv/bin/../lib/python3.6/site.py", line 683, in main
    paths_in_sys = addsitepackages(paths_in_sys)
  File "/Users/dbinetti/repos/barberscore-api/.venv/bin/../lib/python3.6/site.py", line 282, in addsitepackages
    addsitedir(sitedir, known_paths)
  File "/Users/dbinetti/repos/barberscore-api/.venv/bin/../lib/python3.6/site.py", line 204, in addsitedir
    addpackage(sitedir, name, known_paths)
  File "/Users/dbinetti/repos/barberscore-api/.venv/bin/../lib/python3.6/site.py", line 173, in addpackage
    exec(line)
  File "<string>", line 1, in <module>
  File "/Users/dbinetti/repos/barberscore-api/.venv/lib/python3.6/types.py", line 6, in <module>
    import functools as _functools
  File "/Users/dbinetti/repos/barberscore-api/.venv/lib/python3.6/functools.py", line 24, in <module>
    from types import MappingProxyType
ImportError: cannot import name 'MappingProxyType'

Support replica settings

I came into this issue when trying to implement the sorting feature.
I need to create an index for each sorting criteria.

class ProductIndex(AlgoliaIndex):
    ...
    settings = {
        'attributesToIndex': ['title'],
        'attributesForFaceting': ['country', 'city', 'price', 'status'],
        'replicas': [
            'product_by_title_asc',
            'product_by_title_desc',
            ...
        ]
    }
    index_name = 'product'

Unfortunately, it doesn't work and throws the error

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 305, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 356, in execute
output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/site-packages/django/contrib/algoliasearch/management/commands/algolia_reindex.py", line 22, in
 handle
    batch_size=options.get('batchsize', 1000))
  File "/usr/local/lib/python2.7/site-packages/django/contrib/algoliasearch/models.py", line 241, in reindex_all
    self.__client.move_index(self.index_name + '_tmp', self.index_name)
  File "/usr/local/lib/python2.7/site-packages/algoliasearch/client.py", line 282, in move_index
    return self._req(False, path, 'POST', data=request)
  File "/usr/local/lib/python2.7/site-packages/algoliasearch/client.py", line 542, in _req
    return self._transport.req(is_search, path, meth, params, data)
  File "/usr/local/lib/python2.7/site-packages/algoliasearch/transport.py", line 166, in req
    raise e
algoliasearch.helpers.AlgoliaException: cannot move with a primary/replica index as source

I also need to config the ranking/custom ranking function for each replica index but couldn't find the way to deal with it.
Thanks

Aggregators

  • Django version: 2.1
  • Algolia Django integration version: 1.7.0
  • Algolia Client Version: 1.18.1
  • Language Version: 3.7

Description

It is a very common use case to want to search multiple models in the same query. The other Algolia framework clients are implementing this feature, under the name Aggregators (algolia/scout-extended, algolia/search-bundle#257).

Could we implement this in django, too?

Enhancement: Sorting for Models?

Thanks for building this useful package. I looking through the docs tryig to fing something about sorting and wasn't able to find anything. Is this a feature that could be added?

Multiple indexes for the same Model

Hi, I'm trying to build a search feature with two type of permissions on the model fields... Is there a way to index the same Model with multiple indexes (in which I specify the configuration hence the field to show and to index) ?

When I define

class MyAppConfig(AppConfig):
    name = 'my_model'
    def ready(self):
        MyModel = self.get_model('MyModel')
        algoliasearch.register(MyModel, MyModelIndex1)
        algoliasearch.register(MyModel, MyModelIndex2)

I get RegistrationError: <class 'my_app.models.MyModel'> is already registered with Algolia engine

Default batch_size set to None for django 1.7

Hi, I am on django 1.7, and I cannot use the --batchsize command to explicitly set a batch_size.

I'm trying to index hundreds of thousands of entries, and they're being indexed one at a time.

The function def reindex_all(self, batch_size=1000): has a default batch_size of 1000, but gets overwritten in the management command.

    def handle(self, *args, **options):
        '''Run the management command.'''
        self.stdout.write('The following models were reindexed:')
        for model in algoliasearch.get_registered_model():
            adapter = algoliasearch.get_adapter(model)
            if options.get('model', None) and not (model.__name__ in
                                                   options['model']):
                continue

            counts = adapter.reindex_all(
                batch_size=options.get('batchsize', None))
            self.stdout.write('\t* {} --> {}'.format(model.__name__, counts))

I think a simple fix is to not override the default batchsize to None

Proxy method for related (M2M) field giving previously saved values

I followed the documentation to get proxy methods to work but when I save an object with related fields (M2M), the values list reflect what was in the related field before saving.
This is most likely because an instance is saved (thus the post_save signal is triggered) before its related fields are saved (m2m_changed signal).

Following and slightly adapting the documentation, I have the following code:

models.py

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

    def __str__(self):
        return self.username

    class Meta:
        verbose_name = 'Account'
        verbose_name_plural = 'Accounts'


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

    def __str__(self):
        return self.name + ' ' + self.email

    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()]

    class Meta:
        verbose_name = 'Contact'
        verbose_name_plural = 'Contacts'

index.py

from algoliasearch_django import AlgoliaIndex
from algoliasearch_django.decorators import register

from .models import Contact

@register(Contact)
class ContactIndex(AlgoliaIndex):
    fields = (
        'name',
        'email',
        'account_names',
        'account_ids',
    )

    settings = {
        'searchableAttributes': [
            'name',
            'email',
            'account_names',
        ]
    }

I am using:

  • Python 3.6.3
  • Django==1.11.13
  • algoliasearch==1.17.0
  • algoliasearch-django==1.6.0

I believe you will find this interesting: https://stackoverflow.com/questions/23795811/django-accessing-manytomany-fields-from-post-save-signal

Any idea how to get that working?

P.S.: For a ready-to-go and correct test example, the documentation could be updated according to the above models.py and index.py 😉

Make re-indexing configurable

Hello,

The current implementation of reindex does a Model.objects.all(). I am talking about this line

It would nice to have either this accept a different queryset so we could pass our own or have a different method.

Do you think that would make sense?

Support auto-indexing for proxy models

Description

We started using algoliasearch-django recently and we had to compute some fields to be indexed. In our case, the current solution to pre-process fields wasn't suitable as there is a conflict in field names. The model to index already had method/property used in our Django app, and we wanted the same field in Algolia, in a different format.

To implement this, we used a proxy model that we register to our index.

This works pretty well, except for the auto-indexing. Algolia connects the signal receivers to listen for changes on our proxy model, but they never get fired, they are fired through on the base model.

This means we have to do this registration ourselves, which isn't a big deal, but I think this library could benefit from this feature.

Steps To Reproduce

Create a proxy model. This is inspired from the test suite, assuming UnregisteredWebsite is a model similar to Website:

class WebsiteProxy(UnregisteredWebsite):
    class Meta:
        proxy = True

Register it with Algolia:

algolia_engine.register(WebsiteProxy)

Calling save() or delete() on instances of UnregisteredWebsite do not trigger the auto-indexing behaviour.

Possible solutions I've thought of

  1. Add a new argument to the register method, for example: auto_index_model=None
  2. Add a new option to the proxy model Meta class, algolia_auto_index_model
  3. Infer it automatically using WebsiteProxy._meta.proxy and WebsiteProxy._meta.concrete_model

If one of the above is acceptable, I can try to put together a pull request.

Versions

  • Django version: 1.11
  • Algolia Django integration version: 1.6.0
  • Algolia Client Version: 1.17.0
  • Language Version: Python 3.6

How do I index the data that was in the database, before I integrated it with algoliasearch.

How do I index the data that was in the database, before I integrated it with algoliasearch.

python manage.py algolia_reindex: reindex all the registered models.

It only index when object is created or updated. How to index the data that was entered before algoliasearch integration ?

$ python manage.py algolia_reindex
/home/ubuntu/shopsy-pk/API/Provider/models.py:17: RemovedInDjango19Warning: Model class Provider.models.Provider doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
  class Provider(models.Model):
/home/ubuntu/shopsy-pk/API/Provider/models.py:40: RemovedInDjango19Warning: Model class Provider.models.CategoryMappingTemplate doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
  class CategoryMappingTemplate(models.Model):
/home/ubuntu/shopsy-pk/API/Product/models.py:11: RemovedInDjango19Warning: Model class Product.models.Product doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
  class Product(models.Model):
/home/ubuntu/shopsy-pk/API/Product/models.py:85: RemovedInDjango19Warning: Model class Product.models.ProductImage doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
  class ProductImage(models.Model):
The following models were reindexed:
	* Product --> 0

algolia_reindex not found

Hi!
For some reason none of the algolia commands are recognized by django (at least in my computer). I have django 1.11, python 3.5.2, algoliasearch installed, algoliasearch-django installed.
Do you have any clue how to fix this?
python manage.py algolia_reindex Unknown command: 'algolia_reindex' Type 'manage.py help' for usage.

Ability to configure replicas

In the rails integration, we can define the replicas configuration inside the algoliasearch configuration block. Would be great to have the same.

AttributeError: 'int' object has no attribute 'rstrip' when saving model

Hi guys,

I have an algolia index set up as below (index.py):

from django.contrib.algoliasearch import AlgoliaIndex


class ActivityModelIndex(AlgoliaIndex):

    '''Algolia search index for activities'''

    fields = ('activity_type', 'timestamp', 'message', 'additional_data')

    settings = {
        'attributesToIndex': [
            'message', 'additional_data'
        ],

        'numericAttributesToIndex': ['timestamp', 'activity_type']
    }

    index_name = 'activity_index'

The model's pk is id, which is the Django default. Now, Algolia is able to index and apply the settings just fine, but when I try to save a new ActivityModel, I get the following error: AttributeError: 'int' object has no attribute 'rstrip'

The stack trace takes me all the way down to your safe method that is trying to generate a safe URL string from the object's id:

Traceback (most recent call last):
  File "/Users/amrit/Code/orms/activity/tests/viewsets/test_activity_viewset.py", line 24, in setUp
    self.contact = create.contact(user=self.user)
  File "/Users/amrit/Code/orms/utils/testing/create.py", line 54, in contact
    contact = contactmodels.ContactModel.objects.create(**contact_kwargs)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/query.py", line 348, in create
    obj.save(force_insert=True, using=self.db)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/base.py", line 710, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/base.py", line 747, in save_base
    update_fields=update_fields, raw=raw, using=using)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 201, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/Users/amrit/Code/orms/activity/signals/ContactReceivers.py", line 29, in log_contact_created
    activity = ActivityModel.objects.create(**activity_kwargs)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/query.py", line 348, in create
    obj.save(force_insert=True, using=self.db)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/base.py", line 710, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/db/models/base.py", line 747, in save_base
    update_fields=update_fields, raw=raw, using=using)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 201, in send
    response = receiver(signal=self, sender=sender, **named)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/contrib/algoliasearch/registration.py", line 126, in __post_save_receiver
    self.update_obj_index(instance)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/contrib/algoliasearch/registration.py", line 110, in update_obj_index
    adapter.update_obj_index(obj)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/django/contrib/algoliasearch/models.py", line 178, in update_obj_index
    self.__index.save_object(obj)
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/algoliasearch/index.py", line 203, in save_object
    path = '/%s' % safe(obj['objectID'])
  File "/Users/amrit/Code/orms/env/lib/python2.7/site-packages/algoliasearch/helpers.py", line 68, in safe
    return quote(encode(e), safe='')
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1283, in quote
    if not s.rstrip(safe):
AttributeError: 'int' object has no attribute 'rstrip'

Simply changing return quote(encode(e), safe='') to return quote(encode(str(e)), safe='') does the trick, but I figured I would ask you guys whether or not I'm doing something wrong before going in and implementing the fix.

I should note that I am also using Django Rest Framework 3.1.3, Django 1.8.2 and Python 2.7.6

Thanks,
Amrit

Tags has same value for each item in index

I provide a callable for the index' tags but it seems the tag value is only computed once. Indeed, when checking my index in Algolia admin, all items have the same tags (which is 1 item).

I am using Python 2.7.10 and Django 1.8.4 with algoliasearch==1.14.1 and algoliasearch-django==1.5.1.

Here is my code:

# models.py

class JobOffer(models.Model):
    reference_code = models.ForeignKey(
        ReferenceCode,
       blank=True,
        null=True,
        verbose_name=_(u"Code de référence"),
    )

    def reference_code_value(self):
        if self.reference_code:
            return [self.reference_code.value]  # value is a CharField in the ReferenceCode model
        return ['NONE']

# Index

class JobOfferIndex(AlgoliaIndex):
    tags = 'reference_code_value'

Am I misusing the Algolia tags or is my code not correct?

Turn off auto-indexing for certain operations

Hi, is it possible to turn off auto-indexing temporarily? (Like signal disabling?)

I run a nightly operation that runs a denormalization that touches every row, but does not affect fields that are reflected in my search index. However, since I'm touching every row it counts as an operation, and I'm quickly using up my allotment for the month. is there a way to turn off indexing immediately prior to, and re-enable following, my operation?

Thanks.

Problem in generating API key.

I tried registering me models to Algoliasearch and i get this traceback:

(venv)tas@tas-System-Product-Name:~/projects/schoolmgmt/mysite$ python manage.py algolia_reindexTraceback (most recent call last): File "manage.py", line 22, in execute_from_command_line(sys.argv) File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line utility.execute() File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 337, in execute django.setup() File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/django/__init__.py", line 27, in setup apps.populate(settings.INSTALLED_APPS) File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/django/apps/registry.py", line 85, in populate app_config = AppConfig.create(entry) File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/django/apps/config.py", line 94, in create module = import_module(entry) File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module __import__(name) File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/algoliasearch_django/__init__.py", line 7, in from . import registration File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/algoliasearch_django/registration.py", line 189, in algolia_engine = AlgoliaEngine() File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/algoliasearch_django/registration.py", line 38, in _init_ self.client = algoliasearch.Client(app_id, api_key) File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/algoliasearch/client.py", line 89, in _init_ self.api_key = api_key File "/home/tas/projects/schoolmgmt/venv/local/lib/python2.7/site-packages/algoliasearch/client.py", line 122, in api_key if len(value) > MAX_API_KEY_LENGTH:TypeError: object of type 'NoneType'

Apparently there is no API key generated. How do i generate one? I tried this code in mysite/settings.py:
ALGOLIA = { 'APPLICATION_ID': os.getenv('ALGOLIA_APPLICATION_ID'), 'API_KEY': os.getenv('ALGOLIA_API_KEY'), 'AUTO_INDEXING' : True, 'SEARCH_API_KEY': os.getenv('ALGOLIA_SEARCH_API_KEY'), }
Please help.

Handle multiple geolocations

Hi there,

It looks like this SDK doesn't support multiple geolocations whereas the API does. The code wouldn't be too difficult to adapt, something like that would work:

def _validate_geoloc(geo):
    assert set(geo) == {'lat', 'lng'}, 'Invalid geolocation format, requires "lat" and "lng" keys, only.'
if isinstance(loc, tuple):
    tmp['_geoloc'] = {'lat': loc[0], 'lng': loc[1]}
elif isinstance(loc, dict):
    _validate_geoloc(loc)
    tmp['_geoloc'] = loc
elif isinstance(loc, list):
    [_validate_geoloc(geo) for geo in loc]
    tmp['_geoloc'] = loc

Do you accept PRs for this project?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.