Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Haystack: filter query based on multiple items in a list.

I have Event model instances that can belong to one or more Organization model instances. I've implemented haystack 2.0.0 to index all of my Events. Here is an example search index.

class EventIndex(indexes.SearchIndex, indexes.Indexable):

    text = indexes.CharField(document=True, use_template=True)
    organization_slug = indexes.CharField(model_attr='organization__slug',
                        weight=5.0)
    organization_name = indexes.CharField(model_attr='organization__name', 
                        weight=5.0)
    name = indexes.CharField(model_attr='name', weight=10.0)

    ....    

    def get_model(self):
        return Event

    def index_queryset(self):
        return Event.objects.filter()

My question is how do I construct a SearchQuerySet query that filters Events based on one or several Organizations. For example, I want find all Events that belong to "orgnization1" and "organization3" (where the list of organizations can be any length long)

As a Django query it might look something like this:

Event.objects.filter(organization__in=[orgnization1, organization3]).filter(...)

How do I translate this to a haystack query? This is my attempt, but I don't really know what I'm doing...

organization_list = [organization1.slug, organization2.slug]
SearchQuerySet().filter_or(organization__contains=organization_list)

Here is an example of how my models look:

class Event(models.Model):
    name = models.CharField(max_length=64) 
    organization = models.ForeignKey('mymodule.Organization')
    ...

class Organization(models.Model):
    slug = models.SlugField(max_length=64)
    name = models.CharField(max_length=64)
    ... 

Any help is much appreciated.

like image 660
Joe J Avatar asked Feb 03 '12 17:02

Joe J


1 Answers

I think I've found a solution. Just sharing it. Apparently, Haystack has an object called a SQ(), which functions similar to Django's Q() object. I found somewhere that you can invoke the add() method on Django's Q object instances to add more query parameters. Seems to work the same way with SQ.

from haystack.forms import SearchForm
from haystack.query import SQ, SearchQuerySet
from haystack.views import SearchView

class CustomSerchView(SearchView):


    def __call__(self, request):

        self.request = request

        ########### Custom stuff
        user = request.user
        organization_list = [organization1.slug, organization2.slug, ....]

        sq = SQ()
        for slug in organization_list:
            sq.add(SQ(organization_slug=slug), SQ.OR)
        sqs = SearchQuerySet().filter(sq)        
        ##########

        self.form = self.build_form(form_kwargs={'searchqueryset':sqs})
        self.query = self.get_query()
        self.results = self.get_results()
        return self.create_response()
like image 74
Joe J Avatar answered Oct 27 '22 01:10

Joe J