0

我在 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.
4

2 回答 2

2

如果要根据其他字段的值验证某个字段,则需要在表单级别对其进行验证并覆盖该字段的clean方法。这是有关该主题的文档-它们非常好。

class CustomForm(forms.Form):
    custom_field = CustomField()

    def clean(self):
        cleaned_data = super(CustomForm, self).clean()
        custom_field = cleaned_data.get("custom_field")
        ...

如果您查看表单是如何验证的流程,您将看到clean如果所有其他字段独立验证,则该方法运行,因此在此阶段,表单可以被认为是有效的:

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

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

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

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

于 2012-11-01T18:53:16.650 回答
0

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

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

于 2012-11-01T19:10:56.467 回答