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

发布于 2024-07-16 11:10:36 字数 153 浏览 5 评论 0原文

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

我正在尝试访问表单集中的表单,因此 form.data 似乎让我一团糟。

When I have a valid Django form, I can access the data with form.cleaned_data. But how do I get at the data a user entered when the form is not valid i.e., form.is_valid is false.

I'm trying to access forms within a form set, so form.data seems to just give me a mess.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

茶花眉 2024-07-23 11:10:36

您可以使用

form.data['field_name']

这种方式获取分配给该字段的原始值。

You can use

form.data['field_name']

This way you get the raw value assigned to the field.

邮友 2024-07-23 11:10:36

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

其次,一旦我们决定
我们将两个字段中的组合数据
正在考虑无效,我们必须
记得将它们从
已清理的数据。

事实上,Django 目前将
完全清除cleaned_data
字典中如果有错误
表格。 然而,这种行为可能
未来会发生变化,所以这不是
自己清理干净是个坏主意
第一名。

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


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

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

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

See http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation

Secondly, once we have decided that
the combined data in the two fields we
are considering aren't valid, we must
remember to remove them from the
cleaned_data.

In fact, Django will currently
completely wipe out the cleaned_data
dictionary if there are any errors in
the form. However, this behaviour may
change in the future, so it's not a
bad idea to clean up after yourself in
the first place.

The original data is always available in request.POST.


A Comment suggests that the point is to do something that sounds like more sophisticated field-level validation.

Each field is given the unvalidated data, and either returns the valid data or raises an exception.

In each field, any kind of validation can be done on the original contents.

无敌元气妹 2024-07-23 11:10:36

我正在努力解决类似的问题,并在这里遇到了精彩的讨论: https://code.djangoproject.com/ticket/10427< /a>

它根本没有详细记录,但对于实时表单,您可以使用以下命令查看字段的值(如小部件/用户所看到的):

form_name['field_name'].value()

I was struggling with a similar issue, and came across a great discussion here: https://code.djangoproject.com/ticket/10427

It's not at all well documented, but for a live form, you can view a field's value -- as seen by widgets/users -- with the following:

form_name['field_name'].value()
远昼 2024-07-23 11:10:36

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

我想形式如下:

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

1-1。 从请求获取

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

2-1。 的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 。 获取分配给字段的字典

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", '')
        ...

I have many methods. All you can pick.

I suppose the form is like as below:

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

1-1. Get from request

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

2-1. Get the raw value assigned to the field and return the value of the data attribute of field

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

2-2. Get the raw value assigned to the field and return the value of the value attribute of field

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

2-3. Get the dictionary assigned to the fields

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", '')
        ...
稀香 2024-07-23 11:10:36

您可以使用此模式:

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 中的数据未清理:只有字符串值。

You can use this pattern:

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

In your code:

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.

Using form.data is not a good solution. Reasons:

  • If the form has a prefix, the dictionary keys will be prefixed with this prefix.
  • The data in form.data is not cleaned: There are only string values.
寂寞清仓 2024-07-23 11:10:36

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

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

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

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

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

希望这有帮助!

I ran into a similar problem using a formset. In my example, I wanted the user to select a 1st choice before a 2nd choice, but if the 1st choice hit another error, the 'select 1st choice before 2nd' error was also displayed.

To grab the 1st field's uncleaned data, I used this within the form field's clean method:

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

Then, I could test for the presence of data in that field:

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

Hope this helps!

澜川若宁 2024-07-23 11:10:36

您可以通过字段的 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() 之后)

You access the data from either the field's clean() method, or from the form's clean() method. clean() is the function that determines whether the form is valid or not. It's called when is_valid() is called. In form's clean() you have the cleaned_data list when you can run through custom code to make sure it's all checked out. In the widget, you have a clean() also, but it uses a single passed variable. In order to access the field's clean() method, you'll have to subclass it. e.g.:

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

If you want an IntField that doesn't choke on an empty value, for instance, you'd use the above.

clean() on a form kind of works like this:

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

Also you can have a clean_FIELD() function for each field so you can validate each field individually (after the field's clean() is called)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文