简体   繁体   English

Django表单-对象没有属性“请求”错误

[英]Django Forms - object has no attribute 'request' error

I have a search form where I have an optional field city_id 我有一个搜索表单,其中有一个可选字段city_id

My form: 我的表格:

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

This is the error I get: 这是我得到的错误:

object has no attribute 'request' error

Default Haystack SearchForm: 默认的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 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)
....

You need to pass the city_id to the form: 您需要将city_id传递给表单:

def search(self, city_id):
    ...

    sqs = sqs.filter(city_id=city_id) 
    ...

and use it like: 并像这样使用它:

city_id = request.GET.get('city_id')
my_form.search(city_id)

It seems like you are trying to run view-specific code in your form class. 似乎您正在尝试在表单类中运行特定于视图的代码。 The form should only be concerned about validating the data. 该表格仅应关注验证数据。 I assume you have a view function where this form is being instantiated, and from there the view should be the one making the query: 我假设您有一个实例化此表单的视图函数,并且从那里应该是进行查询的视图:

Try in your view: 在您看来:

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'))

And in your form: 并以您的形式:

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

The error statement itself answer your question.You have to pass request to your search function. 错误语句本身会回答您的问题。您必须将请求传递给搜索功能。 Try this : 尝试这个 :

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

Whilst this is bad practise, you could extend the init method as per the following: 虽然这是不好的做法,但是您可以按照以下方法扩展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)

And then whereever you're initialising BusinessSearchForm you pass in request as an additional kwarg: 然后在初始化BusinessSearchForm的任何地方,您都将请求作为附加参数传递:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM