Как проверить форму в запросе на получение? - PullRequest
1 голос
/ 18 января 2012

на моем пути перфекционизма, я здесь, чтобы задавать больше вопросов о не очень хорошо документированных представлениях на основе классов.

Я провожу около 5 часов, изучая представления на основе классов, скрываясьв код, и у меня есть вопрос.

Может быть, то, что я пытаюсь сделать, глупо, и если так, просто скажи это.

Я приведу простой пример:

class SearchFormView(FormView):
    template_name = 'search/search.html'
    form_class = SearchForm

    def get(self, request, *args, **kwargs):
        form = SearchForm(self.request.GET or None)
        if form.is_valid():
            self.mystuff = Stuff.objects.filter(title__icontains=form.cleaned_data['query'])[:10]

        return super(SearchFormView, self).get(request, *args, **kwargs)

Это идеальный допустимый класс (верно?).

У вас есть форма, и вы делаете запрос GET с параметром запроса.

Работает какОчарование.

Но давайте представим ... Я проверяю ввод запроса, чтобы предотвратить какой-либо тип атаки, и вижу, что запрос является вредоносным, поэтому я поставил ошибку проверки.

Со старымфункции, у меня есть экземпляр формы (пустой), и я помещаю в него данные и ошибки проверки, если это необходимо.Я всегда возвращаю этот экземпляр, если он пустой (первый запрос) или если он заполнен ошибками (случай вредоносного запроса).

Проблема связана с представлениями на основе классов.В моем методе get я работаю с дополнительным экземпляром SearchForm , поэтому, если я добавлю валидацию, он будет там, и если я вызову get для отца , он будет использоватьэкземпляр в "form_class", который был бы пустым.

Итак, я думаю, что должен быть способ, которым я всегда использую одну и ту же форму, я имею в виду: я вызываю метод запроса, я выбираю form_class (несоздайте новую форму), передайте данные, подтвердите, и отец вернет эту форму с материалами проверки.

Я не уверен, правильно ли я объяснил.Короче говоря, я создаю копию формы в get, но я возвращаю отец get , у которого есть еще одна копия, которая будет пустой, поэтому мой при отображении шаблона не будет никаких ошибок, потому чтоотправленная форма пуста.

Есть идеи?Спасибо.

Ответы [ 2 ]

3 голосов
/ 18 января 2012

Ваша проблема в том, что super(SearchFormView, self).get(request, *args, **kwargs) отображает свою форму и собственный контекст. Это всего лишь функция просмотра в 3 строки, поэтому вы действительно должны переопределить то, что вам нужно, чтобы изменить его поведение.

   def get(self, request, *args, **kwargs):
        form = SearchForm(self.request.GET or None)
        if form.is_valid():
            self.mystuff = Stuff.objects.filter(title__icontains=form.cleaned_data['query'])[:10]

        return self.render_to_response(self.get_context_data(form=form))

Обновление: альтернативная идея, если вы хотите продолжить использовать супер вызов

def get(self, request, *args, **kwargs):
     self.form = SearchForm(self.request.GET or None)
     if self.form.is_valid():
         self.mystuff = Stuff.objects.filter(title__icontains=form.cleaned_data['query'])[:10]

     return super(SearchFormView, self).get(request, *args, **kwargs)


def get_form(self, form_class):
    """
    Returns an instance of the form to be used in this view.
    """
    return getattr(self, 'form', None) or form_class(**self.get_form_kwargs())
0 голосов
/ 15 марта 2012

Проблема заключается в том, что представления на основе классов Django заполняют форму kwargs только в том случае, если HTTP-метод POST или PUT:

class FormMixin(object):

    def get_form_kwargs(self):
        """
        Returns the keyword arguments for instanciating the form.
        """
        kwargs = {'initial': self.get_initial()}
        if self.request.method in ('POST', 'PUT'):
            kwargs.update({
                'data': self.request.POST,
                'files': self.request.FILES,
            })
        return kwargs

Мне это тоже показалось немного странным, поскольку я иногда использовал форму в запросе GET (например, форму «поиска»), которая должна была выполнить некоторую базовую проверку. Я просто переопределяю метод get_form_kwargs () в таких представлениях, чтобы также заполнить элемент kwargs ['data'], даже если HTTP-метод GET.

...