以我的完美主义方式,我在这里提出更多关于基于类别的不充分记录的观点的问题。
我花了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中创建了一个表单的副本但是我返回父亲获取谁有另一个空的副本,所以当我显示模板时,不会有错误,因为发送的表格是空的。
有什么想法吗?感谢。
答案 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。