Haystack Accessing Stored Fields
May 20, 2010
When you define a search_indexes.py file in Haystack, you can specify additional fields taken from the model. These fields are stored in the index:
import datetime from haystack.indexes import * from haystack import site from myproject.xmlclass.models import XmlClass class XmlClassIndex(SearchIndex): text = CharField(document=True, use_template=True) project = CharField(model_attr='project__name') site.register(XmlClass, XmlClassIndex)
This example adds a project field to the index, which will contain the name attribute on the foreign key called Project. This uses the same double underscore syntax as the query lookup code in Django.
Search Results
This field can be included in the search results by using the get_stored_fields
attribute on the result:
{% for result in page.object_list %} <p><a href="/project/{{result.get_stored_fields.project}}">{{result.get_stored_fields.project}}</a>: <a href="{{ result.object.get_absolute_url }}">{{ result.object.name }}</a></p> {% empty %} <p>No results found.</p> {% endfor %}
You can see here that the project field was referenced in the template as result.get_stored_fields.project
.
Search Form
To add the project as an option on the search form, limiting results to objects just from that project, was more involved.
First of all, rather than importing urls from haystack, we needed to specify the single url manually in urls.py:
url(r'^search/$', SearchView(form_class=MySearchForm), name='haystack.views.haystack_search'),
MySearchForm, referenced here, is a subclass of the haystack ModelSearchForm:
from haystack.forms import ModelSearchForm from django import forms from myproject.project.models import Project class MySearchForm(ModelSearchForm): project = forms.ModelChoiceField(queryset=Project.objects.all(), required=False) def search(self): lQuerySet = super(MySearchForm, self).search() if self.cleaned_data['project']: lQuerySet = lQuerySet.filter(project=self.cleaned_data['project']) return lQuerySet
This adds a new droplist to the form, and populates it with all the projects in the database.
It then redefines search() so that the queryset returned from the default search() is further refined to limit to the project, where the project has been specified.