diff custom_search/forms.py @ 943:cf9918328c64

Haystack tweaks for Django 1.7.7. I had to upgrade to Haystack 2.3.1 to get it to work with Django 1.7.7. I also had to update the Xapian backend. But I ran into problems. On my laptop anyway (Ubuntu 14.0.4), xapian gets mad when search terms are greater than 245 chars (or something) when indexing. So I created a custom field that would simply omit terms greater than 64 chars and used this field everywhere I previously used a CharField. Secondly, the custom search form was broken now. Something changed in the Xapian backend and exact searches stopped working. Fortunately the auto_query (which I was using originally and broke during an upgrade) started working again. So I cut the search form back over to doing an auto_query. I kept the form the same (3 fields) because I didn't want to change the form and I think it's better that way.
author Brian Neal <bgneal@gmail.com>
date Wed, 13 May 2015 20:25:07 -0500
parents 20a3bf7a6370
children 6cc9221d04a7
line wrap: on
line diff
--- a/custom_search/forms.py	Thu Apr 30 20:23:07 2015 -0500
+++ b/custom_search/forms.py	Wed May 13 20:25:07 2015 -0500
@@ -65,6 +65,12 @@
 
         return self.cleaned_data
 
+    def clean_exact(self):
+        exact_field = self.cleaned_data['exact']
+        if "'" in exact_field or '"' in exact_field:
+            raise forms.ValidationError("Quotes are not needed in this field")
+        return exact_field
+
     def search(self):
         if not self.is_valid():
             return self.no_query_found()
@@ -83,24 +89,25 @@
             self.cleaned_data['models'],
             username)
 
-        sqs = self.searchqueryset
-
         # Note that in Haystack 2.x content is untrusted and is automatically
         # auto-escaped for us.
         #
-        # Filter on the q terms; these should be and'ed together:
-        terms = self.cleaned_data['q'].split()
-        for term in terms:
-            sqs = sqs.filter(content=term)
+        # Gather regular search terms
+        terms = ' '.join(self.cleaned_data['q'].split())
 
         # Exact words or phrases:
-        if self.cleaned_data['exact']:
-            sqs = sqs.filter(content__exact=self.cleaned_data['exact'])
+        exact = self.cleaned_data['exact'].strip()
+        if exact:
+            exact = '"{}"'.format(exact)
 
         # Exclude terms:
-        terms = self.cleaned_data['exclude'].split()
-        for term in terms:
-            sqs = sqs.exclude(content=term)
+        exclude = ["-{}".format(term) for term in self.cleaned_data['exclude'].split()]
+        exclude = ' '.join(exclude)
+
+        query = ' '.join([terms, exact, exclude]).strip()
+        logger.debug("auto_query: %s", query)
+
+        sqs = self.searchqueryset.auto_query(query)
 
         if self.load_all:
             sqs = sqs.load_all()