0

I've followed a tutorial to a create search query with Haystack and Whoosh in Django 1.6. The search template works but when filling in and submitting a query the automatic detection of url renders a 404 that generated url; myapp.entry, can't be found. I've tried with changing the url in the ajax.js from /article/search/ to /search/ but it doesn't help. Any ideas?

in settings.py

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'PATH': os.path.join( os.path.dirname(__file__), 'whoosh' ),
    },
}

in views.py

from haystack.query import SearchQuerySet

def search_titles(request):
    #'' - defaultvalue if searchvalue (search_text) is None
    articles =SearchQuerySet().autocomplete(content_auto=request.
POST.get('search_text',''))

    return render(request,'ajax_search.html',{"articles":articles})

in urls.py

urlpatterns = patterns('',
   url(r'^search/',include('haystack.urls')), 

)

in models.py

class Entry(models.Model):
    datetime = models.DateTimeField(auto_now_add = True)
    title = models.CharField(max_length = 70)
    content = models.TextField()
    author = models.ForeignKey(User)
    entry_count = models.PositiveIntegerField()
    n_pingbacks = models.PositiveIntegerField()

    belongsTo = models.ForeignKey(Topic)
    def __unicode__(self):
        return self.title

in search_indexes.py

from haystack import indexes
from myapp.models import Entry
import datetime

class EntryIndex(indexes.SearchIndex, indexes.Indexable):

    text = indexes.CharField(document=True,use_template=True)
    datetime = indexes.DateTimeField(model_attr='datetime')

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

    # get the relevant model
    def get_model(self):
        return Entry

    # returning results from guideline
    def index_queryset(self, using=None):
        """used when the entire index for model is updated """

        return self.get_model().objects.all()

in ajax.js

$(function(){

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

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

    });

});

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

in myapp/templates/search/indexes/myapp/entry_text.txt

{{ object.title }}
{{ object.body }}

in myapp/templates/search/indexes/search.html

{% extends 'base.html' %}

{% block content %}
    <h2>Search</h2>

    <form method="get" action="../">
        <table>
            {{ form.as_table }}
            <tr>
                <td>&nbsp;</td>
                <td>
                    <input type="submit" value="Search">
                </td>
            </tr>
        </table>

        {% if query %}
            <h3>Results</h3>

            {% for result in page.object_list %}
                <p>
                    <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
                </p>
            {% empty %}
                <p>No results found.</p>
            {% endfor %}

            {% if page.has_previous or page.has_next %}
                <div>
                    {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous{% if page.has_previous %}</a>{% endif %}
                    |
                    {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %}
                </div>
            {% endif %}
        {% else %}
            {# Show some example queries to run, maybe query syntax, something else? #}
        {% endif %}
    </form>
{% endblock %}

in myapp/templates/ajax_search.html

{% if articles.count > 0 %}

{% for article in articles %}

   <li><a href="{{article.object.get_absolute_url}}">{{article.object.title}}</a></li>

{% endfor %}

{% else %}

<li>No searchresults to display!</li>

{% endif %}
user1749431
  • 559
  • 6
  • 21

1 Answers1

1

the url in your form is wrong :

Change this : <form method="get" action="../"> by this :

 <form method="get" action="{% url 'haystack_search' %}">
  • Thanks, it seems to be responding better now, it did return one error about "reverse" not being defined in the middle section, line23 of search.html; {{ result.object.title }}. Should this also be changed ? – user1749431 Mar 29 '15 at 23:05
  • If your model does not have a method ``get_absolut_url`` remove it. You should prefere use your 'own' urls mapping with the {% url 'url_name' %} template tag, take a look at the [django url documentation](https://docs.djangoproject.com/en/1.7/topics/http/urls/) – The Django Ninja Mar 29 '15 at 23:27
  • I have added the following to my Entry model after unicode; def get_absolute_url(self): return (reverse('entry', args=[self.title])) but it doesn't doesn't work, am I using the wrong parameters? – user1749431 Mar 29 '15 at 23:54
  • thanks again, solved it with the tags as you suggested. – user1749431 Mar 30 '15 at 01:31