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.
Installation:
pip install django-haystack
Configuration:
add haystack to installed apps
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
#add haystack here
'haystack',
'books'
]
Add back-end settings for the haystack.
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'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.
books/models.py:
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/search_indexes.py 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 [ author.name for author 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.
templates/search/book_text.txt
{{ object.title }}
{% for a in authors%}
{{ a }}
{% endfor %}
Setup:
urls.py
urlpatterns = patterns(
# other urls
url(r'^search/', include('haystack.urls')),
)
build index:
Python manage.py rebuild_index
search query form.
<form action="/search" method="get">
<input name="q" type="text" />
<input type="submit" />
</form>
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 %}