Django Haystack: Filtering by object properties

930 Views Asked by At

I'm trying to build a page that renders searched Oscar products and filters them by their Category using GET attributes. I'm overriding get_queryset and building my object list from there

class ProductSearchView(ListView):
    model = Product
    template_name = "productsearch/product_list.html"
    queryset = Product.objects.none()

    def get_queryset(self):
        word_query_attr = self.request.GET.get('q', None)  # word query
        sqs = SearchQuerySet().models(Product).filter(Q(title__icontains=word_query_attr) |
                                                  Q(category__name__icontains=word_query_attr) |
                                                  Q(upc__icontains=word_query_attr) |
                                                  Q(description__icontains=word_query_attr))
        qs = Product.objects.all()

        if self.request.GET.get('cat', None):
            cat_attr = self.request.GET.get('cat', None)
            category = Category.objects.get(name=cat_attr)
            qs = qs.filter(categories__in=category.get_children())

My question is, can I use SearchQuerySet() to filter through fields from result objects? (in this case, categories from Product objects)

If not, is there an effective way I can create a Product queryset using SearchQuerySet() results? I've tried filtering through IDs

object_ids = [result.object.id for result in sqs]
qs = qs.filter(id__in=object_ids).distinct()

But there are two problems: it isn't scalable (as noted here) and some queries are very slow when I'm dealing with ~900 results.

1

There are 1 best solutions below

1
On

I might be missing something, but the SearchQuerySet filter in your example is already restricting by category name? Could you just change that filter to exact instead of icontains and pass your cat GET param?

sqs = SearchQuerySet().models(Product).filter(
    Q(title__icontains=word_query_attr) |
    Q(upc__icontains=word_query_attr) |
    Q(description__icontains=word_query_attr)
)

cat_attr = self.request.GET.get('cat')
if cat_attr:
    sqs.filter(category__name__exact=cat_attr)

I think Haystack should let you chain filters like that.