I've got a Ticket model that I'm trying to search by its IntegerField priority attribute as a string. I can get haystack+solr to search by the integer value, but not as a string.
I thought you could do this with a prepare_priority function in the search index class, but I'm not having any luck. Here's my search_index.py:
from haystack import indexes
from helpdesk.models import Ticket
class TicketIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
priority = indexes.CharField(model_attr='priority')
def prepare_priority(self, obj):
priorities = {1:'critical', 2:'high', 3:'normal', 4:'low'}
return priorities[obj.priority]
def get_model(self):
return Ticket
def index_queryset(self):
"""Used when the entire index for model is updated."""
return self.get_model().objects.all()
Here's my ticket_text.txt template:
{{ object.title }}
{{ object.priority }}
{{ object.body }}
Am I misunderstanding something or doing something wrong?
Thanks.
prepare_priority() "doesn't work"A SearchIndex is used to convert individual objects of a given model into entries in your Whoosh index. I'll call these entries SearchResults, since that's how they show up in the shell. Now, the fields you defined in TicketIndex are (of course) present on the SearchResults for the Tickets:
>>> from haystack.query import SearchQuerySet
>>> q = SearchQuerySet()
>>> ticket0 = q.all()[0]
>>> type(ticket0)
<class 'haystack.models.SearchResult'>
>>> hasattr(ticket0, 'text') and hasattr(ticket0, 'title') and hasattr(ticket0, 'priority')
True
That means that 'priority' shows up twice--once as independent field and once as part of the content of 'text'. The independent field does go through the prepare_X procedure. The text field goes through a template (where object refers to the original model object, not a dictionary of prepared data).
>>> print ticket0.priority
critical
>>> print ticket0.text
OH NOES!!!!
1
There's a problem. Very problematic. Please fix at once.
In the models:
PRIORITIES = {1:'critical', 2:'high', 3:'normal', 4:'low'}
class Ticket(models.Model):
...
priority = models.IntegerField(choices=PRIORITIES.items())
Use the automatically provided get_priority_display as the model_attr:
class TicketIndex(indexes.SearchIndex):
...
priority = indexes.CharField(model_attr='get_priority_display')
Use get_priority_display in the template:
{{ object.get_priority_display }}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With