Отфильтровать результаты поиска в Django Haystack, например QuerySet?
Можно ли комбинировать поиск в Haystack Django с "встроенными" операциями фильтра QuerySet, особенно с фильтрами с экземплярами Q() и типами поиска, не поддерживаемыми SearchQuerySet? В любом порядке:
haystack-searched -> queryset-filtered
или
queryset-filtered -> haystack-searched
Просмотр документации по Haystack Django не дал никаких указаний, как это сделать.
Ответы
Ответ 1
Вы можете отфильтровать ваш запрос на основе результатов поиска Haystack, используя 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});
Не уверен, как это масштабируется, но для небольших результирующих наборов (несколько сотен, в моем случае) это прекрасно работает.
Ответ 2
Из документов:
SearchQuerySet.load_all (сам)
Эффективно заполняет объекты в результатах поиска. Без использования этот метод, поиск БД выполняется на основе каждого объекта, в результате чего многие индивидуальные поездки в базу данных. Если используется load_all, SearchQuerySet группирует подобные объекты в один запрос, что приводит к тому, что столько запросов, сколько разных типов объектов вернулся.
http://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html#load-all
Поэтому после того, как у вас есть фильтрованный SQS, вы можете сделать load_all() на нем и просто получить доступ к объектам базы данных через SearchResult.object. Например.
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
Ответ 3
Если вы хотите идти в ногу с уместностью, вам нужно получить доступ к объекту из базы данных через "объект":
пример в вашем шаблоне:
{% for result in results %}
{{ result.object.title }}
{{ result.objects.author }}
{% endfor %}
Но это действительно плохо, поскольку сенатор сделает дополнительный запрос, например "SELECT * FROM blah WHERE id = 42" по каждому результату.
Кажется, вы пытаетесь получить этот объект из своей базы данных, потому что вы не поместили лишние поля в свой индекс, не так ли? Если вы добавите заголовок И автора в свой SearchIndex, вы можете просто использовать свои результаты:
{% for result in results %}
{{ result.title }}
{{ result.author }}
{% endfor %}
и избегайте некоторых дополнительных запросов.