Implement search with Django-haystack and Elasticsearch Part-I

Haystack works as a search plugin for Django. You can use different backends Elastic-search, Whose, Sorl, Xapian to search objects. All backends work with the same code. In this post, I am using elastic search as backend.


pip install django-haystack


add haystack to installed apps

#add haystack here


Add back-end settings for the haystack.

'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': '',
'INDEX_NAME': 'haystack_books',

Above settings for elastic search.

Add signal processor for the haystack. This signal will update objects in an index.

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

For This tutorial, I am using below as a model.


class Book(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(unique=True)
created_on = models.DateTimeField(auto_now_add=True)
description = models.TextField()
authors = models.ManyToManyField(settings.AUTH_USER_MODEL)

def __unicode__(self):
return self.title


The purpose of indexing objects is to optimize speed and performance in finding relevant documents for a given search query.
 With search index haystack determines what data should be placed in the index. In haystack, you write a unique index for each model.

create a new file in books/ below code goes

from haystack import indexes
from books.models import Book
    class BookIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True, template_name="search/book_text.txt")
title = indexes.CharField(model_attr='title')
authors = indexes.CharField()
        def get_model(self):
return Book
        def prepare_authors(self, obj):
return [ for a in obj.authors.all()]
        def index_queryset(self, using=None):
return self.get_model().objects.all()

search index will be created by subclassing both haystack.Indexes.SearchIndex and haystack.Indexes.Indexable. Specify index field types by indexes field types(similar to models).

in above index class get_model method used to define a model which you want to create indexes. prepare_fieldname method used to define data for indexing.

Haystack will use a template to index data. these index syntaxes are similar to Django template tags.


{{ object.title }}
{% for a in authors%}
{{ a }}
{% endfor %}


urlpatterns = patterns(
# other urls
url(r'^search/', include('haystack.urls')),

build index:

Python rebuild_index

search query form.

<form action="/search" method="get">
<input name="q" type="text" />
<input type="submit" />

input field q is mandatory for searching.

Display search results:

belove code goes in templates/search/search.html

{% for result in page.object_list %}
{{ result.object.title }}
{{ result.object.description }}
{{ result.object.created_on }}
{% empty %}
No results found.
{% endfor %}

Got error or want to give suggestions please comment below. Happy Coding.

The article was originally published at MicroPyramid blog.