【问题标题】:How to Exclude Fields From Form Validation but Save the Cleaned Data如何从表单验证中排除字段但保存清理后的数据
【发布时间】:2020-12-03 15:46:15
【问题描述】:

编辑:我不是在问如何避免验证模型字段;我明白为什么需要它。我在问当我覆盖表单的 clean() 方法时,我如何才能只跳过我写的检查。我希望clean_data 不经过我编写的其他验证。

假设我有一个带有“保存”和“存档”选项的 ModelForm(即保存以备后用),如果单击它们,它们只会出现在 post_data 中。如果用户单击“保存”,表单将像往常一样通过所有验证(包括 form.clean() 中的一些自定义逻辑)。如果用户单击“归档”,则 form.clean() 中的任何自定义验证都不应运行,但应保存数据。

在 forms.py 中,我尝试将 form.clean() 方法定义为:

def clean(self, full_clean=True):
    cleaned_data = super().clean()
    if full_clean:
        # All my validation
        ...
        ...
    return cleaned_data

然后在我的views.py中:

...
...
if request.method == "POST":
    post_data = request.POST
    if post_data.get('save') != None: # Do all validation
        if form.is_valid():
            form.save()
            cleaned_form = form.cleaned_data
            ...
            ...
        else: # If not valid
            # Do something with the errors
            ...

    elif post_data.get('archive') != None: # Don't do any validation 
        form.is_valid()
        cleaned_form = form.clean(full_clean=False)
        ...
        ...
        form.save()
        ...

问题是,当 form.is_valid() 被调用时 form.clean() 方法被调用,所以所有的自定义验证仍然被执行。我也尝试将full_clean 默认设置为False,但是当我想要它时它不会正确验证。如果我删除第二个 form.is_valid() 调用,clean_data 不会被创建并引发错误。任何建议将不胜感激。

【问题讨论】:

  • 您可以序列化“草稿”数据并将其保存在另一个表/模型中。一旦数据模型受到某些约束,尝试保存无效的数据是很棘手的。例如。如果您有一个not null 字段并且用户没有放置值,那么如何将其保存在您的数据库中?
  • @JônatasCastro 也许我不够清楚。我完全理解模型验证需要完全按照您所说的原因进行。我想要做的是跳过我在覆盖表单的 clean() 方法时编写的验证。例如,我对特定字段进行的一项检查是确保输入在 1 到 9 之间。我希望在不执行自定义验证的情况下清理数据。

标签: django django-models django-forms django-views


【解决方案1】:

覆盖 init() 并根据 post_data 设置一个新字段。

def __init__(self, *args, **kwargs):
    archived = kwargs.pop('archived', None)
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['archived'] = forms.BooleanField(initial=archived, required=False)

然后实际添加到您的表单中

form = MyForm(request.post, archived=post_data.get('archived'))

在您的自定义 clean() 方法中,检查您的 self.fields.get('archived')。

def clean(self):
    if not self.fields.get('archived']:
        # Do your validation

否则它只是跳过自定义验证。

【讨论】:

  • 这是一种有趣的方法,尽管我无法访问 forms.py 中的post_data。您能否详细说明我将如何在 init() 中设置一个新字段?谢谢。
  • 刚刚更新了那篇文章 - 如果有帮助,请告诉我。 @NoahSandler
  • 我的实现方式与您在这里的方式略有不同,但您的想法完全符合我的需要。谢谢!
猜你喜欢
  • 2013-08-30
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2015-08-03
  • 2013-05-26
相关资源
最近更新 更多