form.is_valid()为false时如何访问数据

当我有一个有效的Django表单时,我可以通过form.cleaned_data访问数据。 但是,如何获取用户在表单无效时input的数据,即form.is_valid为false。

我试图访问表单集内的表单,所以form.data似乎只是给我一个烂摊子。

您可以使用

form.data['field_name'] 

这样你可以得到分配给该字段的原始值。

请参阅http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation

其次,一旦我们确定我们正在考虑的两个领域的组合数据是无效的,我们必须记住将它们从清洁数据中移除。

事实上,如果表单中有任何错误,Django目前将彻底清除已经清理好的数据字典。 但是,这种行为在未来可能会发生变化,所以先把自己清理干净不失为一个好主意。

原始数据始终在request.POST可用。


一条评论表明,重点是做一些听起来更复杂的字段级validation。

每个字段都被赋予未validation的数据,并返回有效数据或引发exception。

在每个领域,可以对原始内容进行任何types的validation。

我在类似的问题上挣扎,并在这里遇到了一个很好的讨论: https : //code.djangoproject.com/ticket/10427

它没有被充分logging,但是对于一个现场表单,您可以通过以下方式查看一个字段的值(如小部件/用户所看到的):

 form_name['field_name'].value() 

你可以使用这种模式:

 class MyForm(forms.Form): ... def clean(self): self.saved_data=self.cleaned_data return self.cleaned_data 

在你的代码中:

 if form.is_valid(): form.save() return django.http.HttpResponseRedirect(...) if form.is_bound: form.saved_data['....'] # cleaned_data does not exist any more, but saved_data does. 

使用form.data不是一个好的解决scheme。 原因:

  • 如果表单有一个前缀,字典键将以前缀为前缀。
  • form.data中的数据没有被清除:只有string值。

我有很多方法。 所有你可以select。

我想这个表格就像下面这样:

 class SignupForm(forms.Form): email = forms.CharField(label='email') password = forms.CharField(label='password', widget=forms.PasswordInput) 

1-1。 从request获取

 def signup(req): if req.method == 'POST': email = req.POST.get('email', '') password = req.POST.get('password', '') 

2-1。 获取分配给该字段的raw value并返回字段的data属性的值

 def signup(req): if req.method == 'POST': ... sf = SignupForm(req.POST) email = sf["email"].data password = sf["password"].data ... 

2-2。 获取分配给该字段的原始值并返回字段value属性的value

 def signup(req): if req.method == 'POST': ... sf = SignupForm(req.POST) email = sf["email"].value() password = sf["password"].value() ... 

2-3。 获取分配给字段的dictionary

 def signup(req): if req.method == 'POST': ... sf = SignupForm(req.POST) # print sf.data # <QueryDict: {u'csrfmiddlewaretoken': [u'U0M9skekfcZiyk0DhlLVV1HssoLD6SGv'], u'password': [u''], u'email': [u'hello']}> email = sf.data.get("email", '') password = sf.data.get("password", '') ... 

我遇到了一个类似的问题,使用formset。 在我的示例中,我希望用户在第二次select之前select第一个选项,但是如果第一个select出现另一个错误,则还会显示“在第二个之前select第一个select”错误。

为了获取第一个字段的未清除数据,我在表单域的clean方法中使用了这个:

 dirty_rc1 = self.data[self.prefix + '-reg_choice_1'] 

然后,我可以testing该领域的数据是否存在:

 if not dirty_rc1: raise ValidationError('Make a first choice before second') 

希望这可以帮助!

您可以从字段的clean()方法或表单的clean()方法中访问数据。 clean()是确定表单是否有效的函数。 当调用is_valid()时调用它。 在form的clean()中,当你可以运行自定义代码来确保它们全部被检出时,你有清单数据清单。 在小部件中,你也有一个clean(),但它使用一个传递的variables。 为了访问字段的clean()方法,你必须inheritance它的子类。 例如:

 class BlankIntField(forms.IntegerField): def clean(self, value): if not value: value = 0 return int(value) 

如果你想要一个不憋空的IntField,例如,你可以使用上面的。

清洁()表单上的一种工作是这样的:

 def clean(self): if self.cleaned_data.get('total',-1) <= 0.0: raise forms.ValidationError("'Total must be positive") return self.cleaned_data 

你也可以为每个字段设置一个clean_field()函数,这样你就可以单独validation每个字段(调用字段的clean()之后)