1๐
So this is actually quite easy, as Haystack provides a straight forward way to get all of the fields for the index using:
connections[DEFAULT_ALIAS].get_unified_index()
All that needs to be done is tokenize the search string, remove any that have a token that is a valid field, and run the search on the terms that are left before using the fields in a call to filter.
Iโve released it as a gist as well, but will probably end up packaging it at a later stage
from haystack.constants import DEFAULT_ALIAS
from haystack import connections
class TokenSearchForm(SearchForm):
def prepare_tokens(self):
try:
query = self.cleaned_data.get('q')
except:
return {}
opts = connections[DEFAULT_ALIAS].get_unified_index().fields.keys()
kwargs = {}
query_text = []
for word in query.split(" "):
if ":" in word:
opt,arg = word.split(":",1)
if opt in opts:
kwargs[str(opt)]=arg
else:
query_text.append(word)
self.query_text = " ".join(query_text)
self.kwargs = kwargs
return kwargs
def search(self):
self.query_text = None
kwargs = self.prepare_tokens()
if not self.is_valid():
return self.no_query_found()
if not self.cleaned_data.get('q'):
return self.no_query_found()
sqs = self.searchqueryset.auto_query(self.query_text)
if kwargs:
sqs = sqs.filter(**kwargs)
if self.load_all:
sqs = sqs.load_all()
return sqs
1๐
you can take advantage of the the ability to expand dictionaries into keyword arguments
after applying your regex to filter you search field and search value create a dictionary like
my_search = {'search_field':'search_value'}
search_res = SearchQuerySet().filter(**my_search)
just tested it out in my implementation and worked great! Unless you are worried about users searching fields that they should not be searching/viewing there is no need to verify that it is a valid search field, an invalid search filed will just return no results
- [Answered ]-Operationalerror: database don't exist
- [Answered ]-Creating Django Query Sets to Access Entire Database
- [Answered ]-Django MEDIA_ROOT, MEDIA_URL etc
- [Answered ]-Django AssertTemplateUsed test fails since Upgrade to Django 1.8