I'm working with haystack + Whoosh and DJango to build a basic search engine. What I want to do is that each of my search results will have a "favourites" value (default is 0). And I want to sort these results by this integer with the results with the higher amount of favourites coming first. I've followed the guide on the Haystack tutorial and looked up other answers on the topic but I cannot seem to get it to work.
I have a models.py
that looks like this:
class Recipe(models.Model):
primary_url = models.CharField(max_length=500, null=False, blank=False, primary_key=True)
title = models.CharField(max_length=500)
favourite_count = models.IntegerField(null=False, default= 0)
def __unicode__(self):
return self.title
In my search_indexes.py
, I gave the favourites attribute a name like so:
class RecipeIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
favourite_count = indexes.IntegerField(model_attr='favourite_count', stored=True)
def get_model(self):
return Recipe
def index_queryset(self, using=None):
#Used when entire index for model is updated
return self.get_model().objects.all()
And finally my urls.py
is set up like so:
sqs = SearchQuerySet().order_by('-favourite_count')
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^search/', search_view_factory(view_class=views.mySearchView, template='search/search.html', searchqueryset=sqs, form_class=views.myModelSearchForm))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Despite this, my results are not being sorted correctly. They are still in a random order despite my efforts. I know the urls.py
is understanding my declaration for sqs as it throws an error if I mis-spell it:
KeyError: "No field named 'favrite_count'"
EDIT:
Here is views.mySearchView()
class mySearchView(SearchView):
def __call__(self, request):
"""
Generates the actual response to the search.
Relies on internal, overridable methods to construct the response.
"""
self.request = request
self.form = self.build_form()
#print(self.get_query())
querywords = self.get_query().split()
resultwords = [word for word in querywords if word.lower() not in stopwords]
result = ' '.join(resultwords)
#print(result)
self.query = result
self.results = self.get_results()
return self.create_response()
def get_results(self):
"""
Fetches the results via the form.
Returns an empty list if there's no query to search with.
"""
#sortedQuerySet = sorted(self.form.search(), key=token_similarity)
#return sortedQuerySet
return self.form.search()
def extra_context(self):
request = self.get_query()
if request is not None and not "":
related_recipes = []
words = request.split(' ')
if(len(words) > 1):
for word in words:
temp_list = SearchQuerySet().auto_query(word)[:8]
for obj in temp_list:
if str(self.query).lower() not in str(obj.object.title).lower():
#print(str(self.query).lower()+" is not in "+ str(obj.object.title).lower())
#print('here')
if obj.object.primary_image_url != "test_url":
related_recipes.append(obj)
if len(related_recipes) >= 8:
break
#print(related_recipes)
return {'related': related_recipes}
else:
return {}
EDIT 2:
SO taking my results as is, the order they are being sorted in with the line:
sqs = SearchQuerySet().order_by('-favourite_count')
is like this for the first page:
15
251
10
21
0
15
14
0
0
0
5
8
...
while changing it around to sqs = SearchQuerySet().order_by('favourite_count')
gives back:
0
0
25
7
0
0
0
0
0
0
2
0
7
0
....
Again, the field in question I am sorting by is an IntegerField. Ordering by simple numbers should not be this difficult unless I am missing something.