【问题标题】:Django: simple way to validate combinations of fields?Django:验证字段组合的简单方法?
【发布时间】:2014-03-28 17:08:26
【问题描述】:

在 Django 中,测试之类的方法

a) 两个字段中至少有一个已填写,如果没有则放置错误信息;或

b) 因为一个字段已经填写,另一个字段成为必填字段,并在现在必填字段上放置错误消息

是在form.clean 方法中测试。

这是一项常见且重复的任务。是否有一个库可以简化clean 中此类测试的编写?最好是声明式的?

【问题讨论】:

    标签: python django forms validation


    【解决方案1】:

    如果有一个库可以做到这一点,我会感到惊讶,因为它很难一概而论。例如,我构建了非常具体的错误消息以确保用户知道发生了什么:“既然你填写了 X 和 Y,你还必须包括一个 Z。”

    但是,就您而言,花时间自己做这件事可能是值得的。如果我要这样做,我会创建一个 BaseForm 的子类以在这些情况下使用。这是一个非常粗略的大纲(未经测试):

    class CrossRequirementsForm(BaseForm):
    
        # subclasses set this attribute:
        # cross_requirements_fields = {'foo': ('bar', 'baz',), 'height': ('weight',)}
    
        def clean(self):
            if self.cross_requirements_fields:
                for required_field, if_other_fields = self.cross_requirements_fields.items():
                    if all([self.cleaned_data[f] for f in if_other_fields]):
                        if not self.cleaned_data[required_field]:
                            raise ValidationError('{} is required since {} are set'.format(
                                required_field, if_other_fields
                            ))
    

    那么,你的子类就可以这样做了:

    class MyForm(CrossRequirementsForm):
        cross_requirements_fields = {'foo': ('bar', 'baz',), 'height': ('weight',)}
    

    如果它们覆盖 clean,请确保调用 super.clean。

    【讨论】:

    • 我感觉有些函数式编程要来了
    • 我尽我所能保持我们的代码库干净,因为它可以让我们更快地迭代,这对我们的业务来说非常重要。我的背景是 Lisp :)
    • 具体来说,python 中的函数式习语应该允许组合指定行为的函数式。
    【解决方案2】:

    您可以为以下形式编写简单的 mixin:

    from django.core import forms
    
    class AwesomeFormMixin(object):
        def clean(self):
            for field in self.fields_to_process:
                #process fields here
    
    
    class MyForm(AwesomeFormMixin, forms.Form):
        fields_to_process = ['this_field', 'that_field']
        ...        
        def clean(self):
            super(MyForm, self).clean()
            ...
        ...
    

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 2023-03-08
      • 2012-01-09
      • 2012-10-08
      • 2014-07-15
      • 1970-01-01
      相关资源
      最近更新 更多