0

I'm following a tutorial for Solr django-haystack that uses ajax to return results when a letter is typed. I believe the term for this is called a typehead. Prior to using haystack it worked fine this is the code

def search_title(request):
  if request.method == "GET":
      search_text = request.GET['search_text']
  else:
      search_text = ''

  posts = Post.objects.filter(
      Q(title__contains=search_text) |
      Q(content__contains=search_text)
  )
  context = {
      "posts": posts
  }
  context.update(csrf(request))
  return render(request, "posts/ajax_search.html", context)

I then switched it to use haystack like this

def search_title(request):
 posts = SearchQuerySet().autocomplete(content_auto=request.GET.get('search_text', ''))
 context = {
     "posts": posts
 }
 context.update(csrf(request))
 return render(request, "posts/ajax_search.html", context)

my search_indexes.py

from haystack import indexes
from .models import Post


class PostIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    title = indexes.CharField(model_attr='title')
    publish = indexes.DateTimeField(model_attr='publish')

    content_auto = indexes.EdgeNgramField(model_attr='title')

    def get_model(self):
         return Post

    def index_queryset(self, using=None):
        """Used when the entire index for model is updated."""
        return self.get_model().objects.all()

my post model

class Post(models.Model):
  user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
  title = models.CharField(max_length=120)
  slug = models.SlugField(max_length=200, unique=True)
  image = models.ImageField(upload_to=upload_location,
                          null=True,
                          blank=True,
                          width_field="width_field",
                          height_field="height_field")
  height_field = models.IntegerField(default=0)
  width_field = models.IntegerField(default=0)
  content = models.TextField()
  draft = models.BooleanField(default=False)
  publish = models.DateField(auto_now=False, auto_now_add=False)
  timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
  updated = models.DateTimeField(auto_now=True, auto_now_add=False)
  tags = models.ManyToManyField(Tag)

  objects = PostManager()

  def __str__(self):
      return self.title

  def get_absolute_url(self):
      return reverse("posts:detail", kwargs={"slug": self.slug})

my post_text.txt

{{ object.title }}
{{ object.content }}

and I also changed my ajax_search.html from this

{% if posts.count > 0 %}

{% for post in posts %}
<li><a href="{{ post.get_absolute_url }}" class="list-group-item results">{{    post.title }}</a></li>
{% endfor %}

{% else %}
<li class="list-group-item"> None to show</li>
{% endif %}

to the following

{% if posts.count > 0 %}

{% for post in posts %}
<li><a href="{{ post.object.get_absolute_url }}" class="list-group-item results">{{ post.object.title }}</a></li>
{% endfor %}

{% else %}
<li class="list-group-item"> None to show</li>
{% endif %}

I dont't think the following code matters, But I also don't know what is exactly wrong so heres my ajax.js

  $(function(){

  $('#search').keyup(function() {

      $.ajax({
         type: "GET",
         url: "/posts/search/",
         data: {
             'search_text': $('#search').val(),
             'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
         },
         success: searchSuccess,
         dataType: 'html'
     });
 });
});

function searchSuccess(data, textStatus, jqXHR)
{
$('#search-results').html(data);

my post/urls.py

 from django.conf.urls import url, include
from .views import post_create, post_detail, post_list, post_update, post_delete, post_search, tag_list, search_title

urlpatterns = [
   url(r'^$', post_list, name='list'),
   url(r'^create/$', post_create, name='create'),
   url(r'^search/$', search_title),
   url(r'^search_results/$', post_search, name='search-page'),
   url(r'^tag/(?P<slug>[\w-]+)/$', tag_list, name="tag_list"),
   url(r'^(?P<slug>[\w-]+)/$', post_detail, name='detail'),
   url(r'^(?P<slug>[\w-]+)/edit/$', post_update, name='update'),
   url(r'^(?P<id>\d+)/delete/$', post_delete, name='delete'),
 # url(r'^search/', include('haystack.urls')),
]

versions of everything

Django==1.9.2
django-haystack==2.4.1
pysolr==3.4.0
python 3.5
Solr 4.10.2 

any guidance in the right direction is welcome.

EDIT this is the error message I get in my console

GET http://localhost:8000/posts/search_f/?search_text= 500 (Internal Server Error)    jquery.min.js:4
send @ jquery.min.js:4
n.extend.ajax @ jquery.min.js:4
(anonymous function) @ ajax.js:5
n.event.dispatch @ jquery.min.js:3
r.handle @ jquery.min.js:3

and in my terminal (this error occurs when I press delete in the search field and there are no characters in it)

 Internal Server Error: /posts/search_f/
Traceback (most recent call last):
  File "/Users/ray/Desktop/uply/my-server/lib/python3.5/site-  packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/ray/Desktop/uply/my-server/lib/python3.5/site-  packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/ray/Desktop/uply/my-server/src/posts/views.py", line 186, in    search_title
    posts = SearchQuerySet().autocomplete(content_auto=request.GET.get('search_text', ''))
  File "/Users/ray/Desktop/uply/my-server/lib/python3.5/site-packages/haystack/query.py", line 471, in autocomplete
    return clone.filter(six.moves.reduce(operator.__and__, query_bits))

TypeError: reduce() of empty sequence with no initial value

EDIT

now I'm getting

Model could not be found for SearchResult '<SearchResult: posts.post (pk='10')>'.
[25/Feb/2016 12:13:18] "GET /posts/search/?search_text=lil HTTP/1.1" 200 62
losee
  • 2,190
  • 3
  • 29
  • 55

0 Answers0