[Solved]-Filter Django Haystack results like QuerySet?

12đź‘Ť

âś…

You could filter your queryset based on the results of a Haystack search, using the objects’ PKs:

def view(request):
  if request.GET.get('q'):
    from haystack import ModelSearchForm
    form = ModelSearchForm(request.GET, searchqueryset=None, load_all=True)
    searchqueryset = form.search()
    results = [ r.pk for r in searchqueryset ]

    docs = Document.objects.filter(pk__in=results)
    # do something with your plain old regular queryset

    return render_to_response('results.html', {'documents': docs});

Not sure how this scales, but for small resultsets (a few hundred, in my case), this works fine.

👤ar0n

1đź‘Ť

From the docs:

SearchQuerySet.load_all(self)

Efficiently populates the objects in the search results. Without using
this method, DB lookups are done on a per-object basis, resulting in
many individual trips to the database. If load_all is used, the
SearchQuerySet will group similar objects into a single query,
resulting in only as many queries as there are different object types
returned.

http://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html#load-all

Therefore, after you have a filtered SQS, you can do a load_all() on it and just access the database objects via SearchResult.object. E.g.

sqs = SearchQuerySet()
# filter as needed, then load_all
sqs = sqs.load_all()

for result in sqs:
    my_obj = result.object
    # my_obj is a your model object

0đź‘Ť

If you want to keep up with the pertinence, you have to access the object from the database through “object” :

example in your template:

{% for result in results %}
    {{ result.object.title }}
    {{ result.objects.author }}
{% endfor %}

But this is really bad since haystack will make an extra request like “SELECT * FROM blah WHERE id = 42” on each results.

Seems you’re trying to get those object from your database because you didn’t put some extra fields in your index ins’t it ? If you add the title AND the author in your SearchIndex, then you can just use your results:

{% for result in results %}
    {{ result.title }}
    {{ result.author }}
{% endfor %}

and avoid some extra queries.

👤dzen

Leave a comment