52

当我有一个有效的 Django 表单时,我可以使用 form.cleaned_data 访问数据。但是,当表单无效时,我如何获取用户输入的数据,即 form.is_valid 为假。

我正在尝试访问表单集中的表单,所以 form.data 似乎只是让我一团糟。

4

7 回答 7

52

您可以使用

form.data['field_name']

通过这种方式,您可以获得分配给该字段的原始值。

于 2009-09-17T18:36:49.980 回答
17

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

其次,一旦我们确定我们正在考虑的两个字段中的组合数据无效,我们必须记住将它们从cleaned_data 中删除。

事实上,如果表单中有任何错误,Django 目前会彻底清除cleaned_data 字典。但是,这种行为将来可能会发生变化,因此首先自己清理并不是一个坏主意。

原始数据始终在request.POST.


一个评论表明,关键是做一些听起来像更复杂的字段级验证的事情。

每个字段都被赋予未经验证的数据,并且要么返回有效数据,要么引发异常。

在每个字段中,可以对原始内容进行任何类型的验证。

于 2009-04-09T19:27:13.813 回答
14

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

它根本没有很好的文档记录,但是对于实时表单,您可以查看字段的值 - 正如小部件/用户所看到的那样 - 使用以下内容:

form_name['field_name'].value()
于 2012-06-12T22:51:06.123 回答
10

我有很多方法。所有你可以选择。

我想表格如下:

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字段属性的值

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", '')
        ...
于 2015-07-07T07:50:33.970 回答
5

您可以使用此模式:

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 不是一个好的解决方案。原因:

  • 如果表单有前缀,则字典键将以该前缀作为前缀。
  • form.data 中的数据没有被清理:只有字符串值。
于 2011-05-27T12:17:15.893 回答
4

我使用表单集遇到了类似的问题。在我的示例中,我希望用户在第二个选项之前选择一个第一个选项,但是如果第一个选项遇到另一个错误,也会显示“在第二个选项之前选择第一个选项”错误。

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

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

然后,我可以测试该字段中是否存在数据:

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

希望这可以帮助!

于 2012-03-21T14:57:22.477 回答
1

您可以从字段的 clean() 方法或表单的 clean() 方法访问数据。clean() 是确定表单是否有效的函数。它在 is_valid() 被调用时被调用。在表单的 clean()中,cleaned_data当您可以运行自定义代码以确保已全部签出时,您将获得列表。在小部件中,您也有一个 clean(),但它使用单个传递的变量。为了访问该字段的 clean() 方法,您必须对其进行子类化。例如:

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

例如,如果您想要一个不会阻塞空值的 IntField,则可以使用上述方法。

clean() 在表单上的工作方式如下:

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() 函数,以便您可以单独验证每个字段(在调用字段的 clean() 之后)

于 2009-08-16T22:54:20.610 回答