我有一个搜索表单,其中有一个可选字段city_id
我的表格:
class BusinessSearchForm(SearchForm):
def no_query_found(self):
return self.searchqueryset.all()
def search(self):
sqs = super(BusinessSearchForm, self).search()
# if something goes wrong
if not self.is_valid():
return self.no_query_found()
# filter search results
if 'city_id' in self.request.GET: # or POST
sqs = sqs.filter(city_id=self.request.GET.get('city_id'))
else:
sqs = sqs.filter(...)
return sqs
这是我得到的错误:
object has no attribute 'request' error
默认的Haystack SearchForm:
class SearchForm(forms.Form):
q = forms.CharField(required=False, label=_('Search'),
widget=forms.TextInput(attrs={'type': 'search'}))
def __init__(self, *args, **kwargs):
self.searchqueryset = kwargs.pop('searchqueryset', None)
self.load_all = kwargs.pop('load_all', False)
if self.searchqueryset is None:
self.searchqueryset = SearchQuerySet()
super(SearchForm, self).__init__(*args, **kwargs)
def no_query_found(self):
"""
Determines the behavior when no query was found.
By default, no results are returned (``EmptySearchQuerySet``).
Should you want to show all results, override this method in your
own ``SearchForm`` subclass and do ``return self.searchqueryset.all()``.
"""
return EmptySearchQuerySet()
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.auto_query(self.cleaned_data['q'])
if self.load_all:
sqs = sqs.load_all()
return sqs
def get_suggestion(self):
if not self.is_valid():
return None
return self.searchqueryset.spelling_suggestion(self.cleaned_data['q'])
view.py
query = ''
results = EmptySearchQuerySet()
args = {}
args.update(csrf(request))
if request.GET.get('q'):
form = form_class(request.GET, searchqueryset=searchqueryset,
load_all=load_all)
if form.is_valid():
query = form.cleaned_data['q']
results = form.search()
else:
form = form_class(searchqueryset=searchqueryset,
load_all=load_all)
....
答案 0 :(得分:0)
您需要将city_id传递给表单:
def search(self, city_id):
...
sqs = sqs.filter(city_id=city_id)
...
并使用它:
city_id = request.GET.get('city_id')
my_form.search(city_id)
答案 1 :(得分:0)
您似乎正在尝试在表单类中运行特定于视图的代码。表单应该只关注验证数据。我假设你有一个视图函数,其中实例化了这个表单,从那里视图应该是查询的那个:
试试你的观点:
query = ''
results = EmptySearchQuerySet()
args = {}
args.update(csrf(request))
posted_data = {'q': request.GET.get('city_id') }
form = form_class(posted_data, searchqueryset=searchqueryset, load_all=load_all)
if form.is_valid():
results = form.search(request.GET.get('city_id'))
以你的形式:
def search(self, city_id=None):
sqs = super(BusinessSearchForm, self).search()
if city_id is not None:
sqs = sqs.filter(city_id=city_id)
return sqs
答案 2 :(得分:0)
错误陈述本身会回答您的问题。您必须将请求传递给搜索功能。试试这个:
def search(self,request):
sqs = super(BusinessSearchForm, self).search()
# if something goes wrong
if not self.is_valid():
return self.no_query_found()
# filter search results
if 'city_id' in self.request.GET: # or POST
sqs = sqs.filter(city_id=self.request.GET.get('city_id'))
else:
sqs = sqs.filter(...)
return sqs
答案 3 :(得分:0)
虽然这是不好的做法,但您可以按照以下方式扩展init方法:
class BusinessSearchForm(SearchForm):
def __init__(self, *args, **kwargs):
self.searchqueryset = kwargs.pop('searchqueryset', None)
self.load_all = kwargs.pop('load_all', False)
if self.searchqueryset is None:
self.searchqueryset = SearchQuerySet()
self.request = kwargs.pop('request', None)
super(SearchForm, self).__init__(*args, **kwargs)
然后,当您初始化BusinessSearchForm时,您将请求作为额外的kwarg传递:
if request.GET.get('q'):
form = form_class(request.GET, searchqueryset=searchqueryset,
load_all=load_all, request=request)
if form.is_valid():
query = form.cleaned_data['q']
results = form.search()
else:
form = form_class(searchqueryset=searchqueryset,
load_all=load_all, request=request)