【问题标题】:Check if a form is valid from within a form field [Django]检查表单是否在表单域中有效 [Django]
【发布时间】:2012-11-02 03:16:37
【问题描述】:

我在 Django 中对文本字段表单字段进行了子类化,以便为字段创建我自己的自定义小部件。我想知道是否可以检查表单的所有其他字段是否有效(我希望它的服务器端行为根据其他字段的验证而变化)

看评论

类似:

class CustomField(TextInput):
  def __init__(self, *args, **kwargs):
    ...
    super(CustomField, self).__init__(*args, **kwargs)

  input_type = 'hidden'

  def value_from_datadict(self, data, files, name):
    aws_file_key = data.get(name, None)
    _media_bucket = boto.connect_s3(settings.AWS_ACCESS_KEY_ID,
                                       settings.AWS_SECRET_ACCESS_KEY)\
                            .lookup(settings.AWS_MEDIA_STORAGE_BUCKET_NAME)

    try:
      key = _media_bucket.get_key(aws_file_key)
    except:
      print 'Failed to get key.'
      key = None

    if key and aws_file_key:
      fh = tempfile.TemporaryFile()
      key.get_contents_to_file(fh)
      fh.seek(0)
      files = SimpleUploadedFile(key.name, fh.read())
      ### IF FORM IS VALID DELETE KEY, OTHERWISE, KEEP IT.
      if code_to_check_if_valid:
        _media_bucket.delete_key(key)
      fh.close()
      return files
      ...... etc.

【问题讨论】:

    标签: python django amazon-s3 django-forms boto


    【解决方案1】:

    如果要根据其他字段的值来验证某个字段,则需要在表单级别对其进行验证,并覆盖该字段的clean 方法。 Here's the docs on the subject - 他们非常好。

    class CustomForm(forms.Form):
        custom_field = CustomField()
    
        def clean(self):
            cleaned_data = super(CustomForm, self).clean()
            custom_field = cleaned_data.get("custom_field")
            ...
    

    If you look at the flow of how forms are validated,你会看到clean方法在所有其他字段独立验证的情况下运行,所以在这个阶段,表单可以被认为是有效的:

    这些方法按上面给出的顺序运行,一次一个字段。也就是说,对于表单中的每个字段(按照它们在表单定义中声明的顺序),运行Field.clean() 方法(或其覆盖),然后运行clean_<fieldname>()。最后,一旦为每个字段运行这两个方法,就会执行 Form.clean() 方法或其覆盖。

    无论是否有错误,最终的 clean 方法都会实际运行,因此您必须遍历 cleaned_data 以确保没有错误

    Form 类或子类的 clean() 方法始终运行。如果该方法引发 ValidationError,cleaned_data 将是一个空字典。

    上一段的意思是,如果您要覆盖 Form.clean(),则应该遍历 self.cleaned_data.items(),可能还要考虑表单上的 _errors 字典属性。这样,您就已经知道哪些字段通过了各自的验证要求。

    【讨论】:

      【解决方案2】:

      各个字段的 clean 方法的调用顺序与表单声明顺序或明确指定的顺序相同。 [django source code]

      虽然我不推荐这种方法而不是使用 clean 方法进行多字段验证,但如果您的自定义字段是顺序中的最后一个字段,您可以期望 self._errors 指示所有其他字段是否已通过验证或不是。但是在这个阶段,非字段错误将不可用。

      【讨论】:

        猜你喜欢
        • 2016-12-08
        • 1970-01-01
        • 2013-12-01
        • 2017-09-25
        • 2020-04-04
        • 1970-01-01
        • 1970-01-01
        • 2017-07-27
        • 2016-05-03
        相关资源
        最近更新 更多