django haystack autocomplete
Asked Answered
J

3

7

I am trying to use django-haystack (been around 2 days now), and I have got the basic Getting Started example working and it looks very impressive. I would now like to try the autocomplete function on haystack.

http://readthedocs.org/docs/django-haystack/en/v1.2.4/autocomplete.html

The first part seems fine: "Setting up the data" seems simple enough. However, I am not sure where the "Performing the Query" needs to be written: i.e in which view should I include:

from haystack.query import SearchQuerySet
sqs = SearchQuerySet().filter(content_auto=request.GET.get('q', ''))

My current urls.py is simple and set up as follows:

urlpatterns = patterns('',
    # Examples:
    ('^hello/$', hello),
    (r'^$', hello), 
    (r'^search/', include('haystack.urls')),
    # url(r'^$', 'mysite.views.home', name='home'),
    # url(r'^mysite/', include('mysite.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    #url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)

Looking at the following blog:

http://tech.agilitynerd.com/haystack-search-result-ordering-and-pre-rende

I would like to have something like:

url(r'^search/', SearchView(load_all=False,searchqueryset=sqs),name='haystack_search'), 

but, where should the sqs be specified? in the urls.py or views.py? I tried both, but they give me a name error "request" not found on the sqs statement.

Jeanajeanbaptiste answered 6/2, 2012 at 16:22 Comment(0)
D
4

Usually this would be in your own haystack urls, haystack.urls in your current urls.py is pointing to the default urls. Create a file haystack_urls.py and in your urls.py add it e.g.

url(r'^search/', include('yourproject.haystack_urls')),

in that file you can then add your custom code e.g.

from haystack.views import SearchView
from haystack.query import SearchQuerySet

sqs = SearchQuerySet() # edit remove line that was incorret

urlpatterns = patterns('haystack.views',
    url(r'^&', SearchView(load_all=False,searchqueryset=sqs),name='haystack_search'), 
)

to wrap a view for request try something like

class SearchWithRequest(SearchView):

    __name__ = 'SearchWithRequest'

    def build_form(self, form_kwargs=None):
        if form_kwargs is None:
            form_kwargs = {}

        if self.searchqueryset is None:
            sqs = SearchQuerySet().filter(content_auto=self.request.GET.get('q', ''))
            form_kwargs['searchqueryset'] = sqs

        return super(SearchWithRequest, self).build_form(form_kwargs)
Donee answered 6/2, 2012 at 16:32 Comment(9)
Hi JamesO: thanks again for rescuing me. I tried implementing what you have suggested, but I still get the name error on "request". I have pasted the code and traceback on: dpaste.com/698473 I am not sure why I am getting this request error.Jeanajeanbaptiste
ah sorry of course, request is not available, you need to wrap it in your own custom view, which would have access to request... eg a view that sets sqs as you already have abd returns readthedocs.org/docs/django-haystack/en/v1.2.4/…Donee
James, what do you mean by abd returns? (sorry, never heard that). Ok. So you mean to say that i should write a views.py function which returns sqs? Should the class be something like: class MySearchView(SearchView): then def sqs(self): sqs = SearchQuerySet().filter(content_auto=request.GET.get('q', '')) return sqs ? But I cant see how I can pass this on sqs = SearchQuerySet(). Thanks againJeanajeanbaptiste
that should have been and not abd, sorry can't type :/, see my edit for an exampleDonee
JamesO, I have tried to follow your code using super classes. As I understand you inherit the SearchView whilst adding sqs to it. However, it still does not seem to work. I have posted the code:dpaste.com/699212 Can you tell me where I am going wrong? I tried using sqs = SearchQuerySet() and sqs=SearchWithRequest() but none of them show me autocomplete. Infact sqs=SearchWithRequest() thorws a sqs not defined error. Would appreciate your comments. Thanks.Jeanajeanbaptiste
SearchWithRequest is a view, get rid of sqs=SearchWithRequest then call a url like ... urlpatterns = patterns('haystack.views', url(r'^$', SearchWithRequest(), name='haystack_search')) ... note that you don't need to pass sqs as it is set within the view.Donee
Hi JamesO, sorry for the delay in replying: I was AFK all of yesterday. I have tried "urlpatterns = patterns('haystack.views', url(r'^$', SearchWithRequest(), name='haystack_search'))" and it seems to work with no errors, however, I dont see the autocomplete feature kick in. I thought autocomplete would guess the word as I type it, but it dosent seem to do this.Jeanajeanbaptiste
JamesO, Also, haystack manual says that SearchView is not thread safe. So, I changed my URL conf to:"urlpatterns = patterns('haystack.views',url(r'^$',search_view_factory(view_class=SearchWithRequest(),#load_all=False,#template='my/special/path/john_search.html',#searchqueryset=sqs,#form_class=ModelSearchForm), name='haystack_search'),)" but this throws me a TypeError: "Exception Type: TypeError at /search/ Exception Value: __call__() takes exactly 2 arguments (1 given)". Any clues as to why is this? Thanks a tonne for your time.Jeanajeanbaptiste
JamesO, I got search_view_factory working now. I see no errors. Everything seems to work fine, except that I do not get any "autocomplete" words when I enter a search. I have rebuilt and updated the index according to haystack "python manage.py build_index" but I still do not see any autocomplete words :(Jeanajeanbaptiste
C
1

The solution of JamesO was not working for me, so i defined a custom form class, which is actually overrides the 'search' method only. So, in general, you've got to try

  • At your urls.py use FacetedSearchView insted of basic_search or SearchView.
  • Create your own form class, overriding the search method:

    class FacetedSearchFormWithAuto(FacetedSearchForm):          
        def search(self):                        
            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.autocomplete(content_auto=self.cleaned_data['q'])
    
            if self.load_all:
                sqs = sqs.load_all()    
    
            for facet in self.selected_facets:
                if ":" not in facet:
                    continue
    
                field, value = facet.split(":", 1)
    
                if value:
                    sqs = sqs.narrow(u'%s:"%s"' % (field, sqs.query.clean(value)))
    
            return sqs
    
  • specify form_class in FacetedSearchView form_class=FacetedSearchFormWithAuto

Curvy answered 24/10, 2012 at 11:50 Comment(1)
content_auto==self -> content_auto=selfInclude
A
1

If you need help with autocomplete, I think this would be good for you, it's complete solution Django-haystack full text search working but facets don't

Almaalmaata answered 9/2, 2014 at 20:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.