Search code examples
django-haystack

django haystack custom form


I'm trying to make a custom search form using django haystack, i just modify from haystack's documentation :

forms.py

from django import forms
from haystack.forms import SearchForm

class DateRangeSearchForm(SearchForm):
    start_date = forms.DateField(required=False)
    end_date = forms.DateField(required=False)

   def search(self):
        # First, store the SearchQuerySet received from other processing.
        sqs = super(DateRangeSearchForm, self).search()

        # Check to see if a start_date was chosen.
        if self.cleaned_data['start_date']:
            sqs = sqs.filter(pub_date__gte=self.cleaned_data['start_date'])

        # Check to see if an end_date was chosen.
        if self.cleaned_data['end_date']:
            sqs = sqs.filter(pub_date__lte=self.cleaned_data['end_date'])

        return sqs

to :

from django import forms
from haystack.forms import HighlightedModelSearchForm

class CustomSearchForm(HighlightedModelSearchForm):
    title   = forms.CharField(max_length = 100, required = False)
    content = forms.CharField(max_length = 100, required = False)
    date_added = forms.DateField(required = False)
    post_by = forms.CharField(max_length = 100, required = False)

    def search(self):
        sqs = super(CustomSearchForm, self).search()
        if self.cleaned_data['post_by']:
            sqs = sqs.filter(content = self.cleaned_data['post_by'])
        if self.cleaned_data['title']:
            sqs = sqs.filter(content = self.cleaned_data['title'])
        if self.cleaned_data['content']:
            sqs = sqs.filter(content = self.cleaned_data['content'])
        if self.cleaned_data['date_added']:
            sqs = sqs.filter(content = self.cleaned_data['date_added']) 
        return sqs

haystack .urls :

urlpatterns = patterns('haystack.views',
    url(r'^$', search_view_factory(view_class = SearchView, form_class = CustomSearchForm), name='haystack_search'),
)

when i go to the url, it says : AttributeError at /search/

'CustomSearchForm' object has no attribute 'cleaned_data'

can you guys help me? thx

Then i try to comment the search method, but when i submit a word into the custom field, the result is always nothing, only when i submit a word to non-custom field it can gimme the result i want, already tried to understand this all day long, pls help


Solution

  • I know this is a bit old question, but to help others who may be viewing this and wondering the same thing, this is how I got it working in the same situation.

    Something along these lines:

    ...
    def search(self)
        sqs=super(MyFooSearchForm, self).search()
    
        if self.is_valid() and self.cleaned_data['foo']:
            sqs = sqs.filter(foostuff__exact=self.cleaned_data['foo'])
    
        return sqs
    

    Basically, I added 'self.is_valid and' before self.cleaned_data[''] this got rid of the error for me. Hope this helps.

    So,

    def search(self):
        sqs = super(CustomSearchForm, self).search()
        if self.cleaned_data['post_by']:
            sqs = sqs.filter(content = self.cleaned_data['post_by'])
        if self.cleaned_data['title']:
            sqs = sqs.filter(content = self.cleaned_data['title'])
        if self.cleaned_data['content']:
            sqs = sqs.filter(content = self.cleaned_data['content'])
        if self.cleaned_data['date_added']:
            sqs = sqs.filter(content = self.cleaned_data['date_added']) 
        return sqs
    

    would become:

    def search(self):
        sqs = super(CustomSearchForm, self).search()
        if self.is_valid() and self.cleaned_data['post_by']:
            sqs = sqs.filter(content = self.cleaned_data['post_by'])
        if self.is_valid() and self.cleaned_data['title']:
            sqs = sqs.filter(content = self.cleaned_data['title'])
        if self.is_valid() and self.cleaned_data['content']:
            sqs = sqs.filter(content = self.cleaned_data['content'])
        if self.is_valid() and self.cleaned_data['date_added']:
            sqs = sqs.filter(content = self.cleaned_data['date_added']) 
        return sqs
    

    There may be a better way to do this, and I'm a relative beginner for django/python but it worked for me.