Commit 0aa85094 authored by fred's avatar fred

use haystack to fill a 'related' section down in the page

parent fb504721
......@@ -14,6 +14,7 @@ from datetime import datetime, timedelta
from emissions.utils import period_program
from panikweb import utils
from panikweb import search
register = template.Library()
......@@ -217,3 +218,8 @@ def rfc822(datetime):
if datetime is None:
return ''
return email.utils.formatdate(time.mktime(datetime.timetuple()))
@register.inclusion_tag('includes/related.html', takes_context=False)
def related_objects(object):
sqs = search.MoreLikeThisSearchQuerySet()
return {'more_like_this': sqs.more_like_this(object)[:12]}
import haystack.backends.solr_backend
from haystack.query import SearchQuerySet
from haystack.constants import ID, DJANGO_CT, DJANGO_ID
from haystack.utils import get_identifier
from django.conf import settings
class MoreLikeThisSearchQuerySet(SearchQuerySet):
def more_like_this(self, model_instance, **kwargs):
clone = self._clone()
clone.query.more_like_this(model_instance, **kwargs)
return clone
class CustomSolrSearchQuery(haystack.backends.solr_backend.SolrSearchQuery):
def more_like_this(self, model_instance, **kwargs):
self._more_like_this = True
self._mlt_instance = model_instance
def run_mlt(self, **kwargs):
"""Builds and executes the query. Returns a list of search results."""
if self._more_like_this is False or self._mlt_instance is None:
raise MoreLikeThisError("No instance was provided to determine 'More Like This' results.")
additional_query_string = self.build_query()
search_kwargs = {
'start_offset': self.start_offset,
'result_class': self.result_class,
'models': self.models,
'mlt.fl': 'tags',
}
if self.end_offset is not None:
search_kwargs['end_offset'] = self.end_offset - self.start_offset
results = self.backend.more_like_this(self._mlt_instance, additional_query_string, **search_kwargs)
self._results = results.get('results', [])
self._hit_count = results.get('hits', 0)
class CustomSolrSearchBackend(haystack.backends.solr_backend.SolrSearchBackend):
def more_like_this(self, model_instance, additional_query_string=None,
start_offset=0, end_offset=None, models=None,
limit_to_registered_models=None, result_class=None, **kwargs):
from haystack import connections
# Deferred models will have a different class ("RealClass_Deferred_fieldname")
# which won't be in our registry:
model_klass = model_instance._meta.concrete_model
index = connections[self.connection_alias].get_unified_index().get_index(model_klass)
field_name = index.get_content_field()
params = {
'fl': '*,score',
'mlt.fl': 'text,title',
'mlt.qf': 'text^0.3 tags^2.0 title^1.0',
}
if start_offset is not None:
params['start'] = start_offset
if end_offset is not None:
params['rows'] = end_offset
narrow_queries = set()
if limit_to_registered_models is None:
limit_to_registered_models = getattr(settings, 'HAYSTACK_LIMIT_TO_REGISTERED_MODELS', True)
if models and len(models):
model_choices = sorted(['%s.%s' % (model._meta.app_label, model._meta.module_name) for model in models])
elif limit_to_registered_models:
# Using narrow queries, limit the results to only models handled
# with the current routers.
model_choices = self.build_models_list()
else:
model_choices = []
if len(model_choices) > 0:
if narrow_queries is None:
narrow_queries = set()
narrow_queries.add('%s:(%s)' % (DJANGO_CT, ' OR '.join(model_choices)))
if additional_query_string:
narrow_queries.add(additional_query_string)
if narrow_queries:
params['fq'] = list(narrow_queries)
query = "%s:%s" % (ID, get_identifier(model_instance))
try:
raw_results = self.conn.more_like_this(query, field_name, **params)
except (IOError, SolrError) as e:
if not self.silently_fail:
raise
self.log.error("Failed to fetch More Like This from Solr for document '%s': %s", query, e)
raw_results = EmptyResults()
return self._process_results(raw_results, result_class=result_class)
haystack.backends.solr_backend.SolrEngine.query = CustomSolrSearchQuery
haystack.backends.solr_backend.SolrEngine.backend = CustomSolrSearchBackend
from haystack.views import search_view_factory, FacetedSearchView
from haystack.forms import FacetedSearchForm
from haystack.query import SearchQuerySet
class SearchView(FacetedSearchView):
......
......@@ -66,21 +66,10 @@
</div>
</div>
{% endblock %}
{% block related %}
{% if related %}
<div class="padded">
<div class="wrapper">
<h2>Related</h2>
<ul class="custom columns list">
{% for result in related %}
<li class="item {% if episode.emission.categories.all.count = 0 %}nocat{% endif %} {% for category in episode.emission.categories.all %} {{ category|slugify }}{% endfor %}">
{% search_result_template result %}
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% endblock %}
{% block links %}
{% endblock %}
{% block related %}
{% related_objects object=emission %}
{% endblock %}
......@@ -4,3 +4,6 @@
{% load staticfiles %}
{% block title %}{{ episode.title }} - {{ episode.emission.title }} {% endblock %}
{% block related %}
{% related_objects object=episode %}
{% endblock %}
......@@ -34,19 +34,7 @@
</div>
</div>
{% endblock %}
{% block related %}
{% if related %}
<div class="padded">
<div class="wrapper">
<h2>Related</h2>
<ul class="custom columns list">
{% for result in related %}
<li class="item {% if episode.emission.categories.all.count = 0 %}nocat{% endif %} {% for category in episode.emission.categories.all %} {{ category|slugify }}{% endfor %}">
{% search_result_template result %}
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% related_objects object=newsitem %}
{% endblock %}
{% load paniktags %}
<div class="padded">
<div class="wrapper">
<h2>Related</h2>
<ul id="search-results" class="list columns padded cf">
{% for result in more_like_this %}
{% if result.object.title %}
<li class="ellipsis">
{% search_result_template result %}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment