在get请求中验证表单,如何?

时间:2012-01-18 18:02:30

标签: python django django-class-based-views

以我的完美主义方式,我在这里提出更多关于基于类别的不充分记录的观点的问题。

我花了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中创建了一个表单的副本但是我返回父亲获取谁有另一个空的副本,所以当我显示模板时,不会有错误,因为发送的表格是空的。

有什么想法吗?感谢。

2 个答案:

答案 0 :(得分:3)

您的问题是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())

答案 1 :(得分:0)

问题似乎是,如果HTTP方法是POST或PUT,基于Django类的视图只填充表单kwargs:

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。