Django Forms - 对象没有属性' request'错误

时间:2015-03-23 15:40:52

标签: python django search

我有一个搜索表单,其中有一个可选字段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)
....

4 个答案:

答案 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)