【问题标题】:How do I forcefully clean a field and redisplay it in Django?如何强制清理字段并在 Django 中重新显示?
【发布时间】:2010-10-24 21:17:41
【问题描述】:

如何清理表单中的数据并重新显示清理后的数据而不是提交的数据?

我的表单中有几个字段,每次用户提交它时,它都应该重新显示用户输入的值。但是,我想为用户清理和更新一些字段。更具体地说,我有一个字段FriendlyIntegerField(forms.CharField),在该字段中我覆盖to_python,不仅调用int(str(value)),而且还将任何负数设置为0等。我不想重新显示包含无效数据的表单并拥有用户自己修复它(这就是 Django 希望我这样做的方式)。

我没有问题清理数据并将其用于我的视图功能的其余部分,但是如何使用这些数据更新实际表单?

顺便说一句,表单不反映我的数据模型中的结构,因此继承自 Form,而不是 ModelForm

编辑:

我的字段(精简版)如下所示:

class FriendlyIntegerField(forms.CharField):
    def to_python(self, value):
        try:
            return str(int(str(value).replace(' ','')))
        except:
            raise forms.ValidationError('some error msg')

我的表单(精简版)如下所示:

class SearchForm(forms.Form):
    price_from = FriendlyIntegerField()
    price_to = FriendlyIntegerField() 

我的观点:

def search(request, key):
    if request.method == 'POST':
        form = SearchForm(request.REQUEST)
        if not form.is_valid():
            print "Form not valid"
    else:
        form = SearchForm()
    return render_to_response('path_to_template', {'form' : form}

【问题讨论】:

  • 附带说明,您应该注意这一点。我不记得我在哪里读过它,但显然改变用户输入的值可能会让最终用户感到困惑。简单地告诉他们不允许负值并重新显示他们的(错误的)输入可以证明比您想象的更加用户友好。
  • 我绝对同意 LaundroMat。默默地改变用户输入通常不是一个好主意。负数可能不是最好的例子,我可能会在最终版本中跳过它。但是,我确实想删除数字中的空格。该字段代表价格,我认为将“250 000”自动更改为“250000”是个好主意。

标签: python django


【解决方案1】:

如果在您使用 is_valid() 清理表单后,您使用视图呈现清理后的表单,而不是重定向到新页面,您将在页面中看到清理后的数据。

(如果您希望用户看到这些清理过的数据然后正确提交,您可以使用隐藏字段来跟踪表单数据是否已经被清理过,但这并非没有复杂性......)

【讨论】:

  • 您确定重新显示表单时应该呈现清理后的数据,而不是原始数据吗?我已经在上面发布了我的代码的精简版本,如果你能看看并检查你是否能看到为什么没有呈现清理后的数据,我将不胜感激。例如,如果我输入一个带有空格的数字,例如“42 43”,我希望它根据您在此处所说的内容呈现为“4243”,但它仍然呈现为“42 43”跨度>
  • 在 clean_foo(self) 方法中修复它,并记住在它的末尾返回你的清理值。想要清理数据(并展示清理的效果),hacking to_python 不是合适的地方
  • 好的,我改为使用常规 CharField,并在 SearchForm.clean_price_from() 中进行清理,返回清理后的值。我的观点与上面相同,只是我在“else”之前记录了 form.cleaned_data['price_from']。记录的数据被清除,重新显示的表格没有。
  • 另外,浏览 Django 的源代码,似乎并不意味着应该重新显示清理过的数据。这是我对django/form/forms.py的理解:一个绑定的表单有一个BoundField,它是从表单的原始字段初始化的。渲染BoundField时,用作值的数据是从原始字段中的datadict中提取的,而不是从self.cleaned_data中提取的。我也看不到从 self.cleaned_data 更新的原始字段。
  • @knatten 你是对的,你可以找到解决方法here
猜你喜欢
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多