comparison custom_search/forms.py @ 753:ad53d929281a

For issue #62, upgrade Haystack from 1.2.7 to 2.1.0.
author Brian Neal <bgneal@gmail.com>
date Fri, 03 Jan 2014 19:01:18 -0600
parents 99d7bf8cd712
children 20a3bf7a6370
comparison
equal deleted inserted replaced
752:95f4e7f352fd 753:ad53d929281a
1 """ 1 """
2 This module contains custom forms to tailor the Haystack search application to 2 This module contains custom forms to tailor the Haystack search application to
3 our needs. 3 our needs.
4 4
5 """ 5 """
6 import logging
7
6 from django import forms 8 from django import forms
9 from django.conf import settings
7 from haystack.forms import ModelSearchForm 10 from haystack.forms import ModelSearchForm
8 11
9 12
10 MODEL_CHOICES = ( 13 MODEL_CHOICES = (
11 ('forums.topic', 'Forum Topics'), 14 ('forums.topic', 'Forum Topics'),
16 ('downloads.download', 'Downloads'), 19 ('downloads.download', 'Downloads'),
17 ('podcast.item', 'Podcasts'), 20 ('podcast.item', 'Podcasts'),
18 ('ygroup.post', 'Yahoo Group Archives'), 21 ('ygroup.post', 'Yahoo Group Archives'),
19 ) 22 )
20 23
24 logger = logging.getLogger(__name__)
25
21 26
22 class CustomModelSearchForm(ModelSearchForm): 27 class CustomModelSearchForm(ModelSearchForm):
23 """ 28 """
24 This customized ModelSearchForm allows us to explictly label and order 29 This customized ModelSearchForm allows us to explictly label and order
25 the model choices. 30 the model choices.
26 31
32 We also provide "all words", "exact phrase", and "exclude" text input boxes.
33 Haystack 2.1.0's auto_query() function did not seem to work right so we just
34 rolled our own.
35
27 """ 36 """
28 q = forms.CharField(required=False, label='', 37 q = forms.CharField(required=False, label='All these words',
29 widget=forms.TextInput(attrs={'type': 'search', 38 widget=forms.TextInput(attrs={'type': 'search', 'class': 'search',
30 'class': 'search', 39 'size': 48}))
31 'size': 48, 40 exact = forms.CharField(required=False, label='This exact word or phrase',
32 })) 41 widget=forms.TextInput(attrs={'type': 'search', 'class': 'search',
42 'size': 48}))
43 exclude = forms.CharField(required=False, label='None of these words',
44 widget=forms.TextInput(attrs={'type': 'search', 'class': 'search',
45 'size': 48}))
33 46
34 def __init__(self, *args, **kwargs): 47 def __init__(self, *args, **kwargs):
35 super(CustomModelSearchForm, self).__init__(*args, **kwargs) 48 super(CustomModelSearchForm, self).__init__(*args, **kwargs)
36 self.fields['models'] = forms.MultipleChoiceField(choices=MODEL_CHOICES, 49 self.fields['models'] = forms.MultipleChoiceField(choices=MODEL_CHOICES,
37 label='', widget=forms.CheckboxSelectMultiple) 50 label='Search in', widget=forms.CheckboxSelectMultiple)
51
52 def clean(self):
53 if not settings.SEARCH_QUEUE_ENABLED:
54 raise forms.ValidationError("Our search function is offline for "
55 "maintenance. Please try again later. "
56 "We apologize for any inconvenience.")
57
58 if not (self.cleaned_data['q'] or self.cleaned_data['exact'] or
59 self.cleaned_data['exclude']):
60 raise forms.ValidationError('Please supply some search terms')
61
62 return self.cleaned_data
63
64 def search(self):
65 if not self.is_valid():
66 return self.no_query_found()
67
68 logger.info('Search executed: /%s/%s/%s/ in %s',
69 self.cleaned_data['q'],
70 self.cleaned_data['exact'],
71 self.cleaned_data['exclude'],
72 self.cleaned_data['models'])
73
74 sqs = self.searchqueryset
75
76 # Note that in Haystack 2.x content is untrusted and is automatically
77 # auto-escaped for us.
78 #
79 # Filter on the q terms; these should be and'ed together:
80 terms = self.cleaned_data['q'].split()
81 for term in terms:
82 sqs = sqs.filter(content=term)
83
84 # Exact words or phrases:
85 if self.cleaned_data['exact']:
86 sqs = sqs.filter(content__exact=self.cleaned_data['exact'])
87
88 # Exclude terms:
89 terms = self.cleaned_data['exclude'].split()
90 for term in terms:
91 sqs = sqs.exclude(content=term)
92
93 if self.load_all:
94 sqs = sqs.load_all()
95
96 # Apply model filtering
97 sqs = sqs.models(*self.get_models())
98
99 return sqs