Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 如果设置了布尔字段,则仅验证某些字段_Django_Django Forms_Django Validation - Fatal编程技术网

Django 如果设置了布尔字段,则仅验证某些字段

Django 如果设置了布尔字段,则仅验证某些字段,django,django-forms,django-validation,Django,Django Forms,Django Validation,场景:我正在生成订单。像地球上的其他订单一样,它有单独的发票发货地址。我刚刚添加了一个“使用账单地址”复选框,让用户节省时间 问题是,航运领域仍然存在。如果用户没有输入任何发货地址数据(例如,如果他们想使用账单地址),则验证将失败 我想我要做的是覆盖这些重复字段的ModelForm验证。在那里,如果复选框被选中(不确定如何从验证器中获取数据),我将返回计费版本。如果没有检查,我会将其传递回原始验证 听起来像个计划,不是吗?我在第一个跨栏时摔倒了。我的clean_函数不工作。看起来他们连电话都没有

场景:我正在生成订单。像地球上的其他订单一样,它有单独的发票发货地址。我刚刚添加了一个“使用账单地址”复选框,让用户节省时间

问题是,航运领域仍然存在。如果用户没有输入任何发货地址数据(例如,如果他们想使用账单地址),则验证将失败

我想我要做的是覆盖这些重复字段的ModelForm验证。在那里,如果复选框被选中(不确定如何从验证器中获取数据),我将返回计费版本。如果没有检查,我会将其传递回原始验证

听起来像个计划,不是吗?我在第一个跨栏时摔倒了。我的
clean_函数
不工作。看起来他们连电话都没有

下面是一些代码:

# shipping_street is a field in my Order Model

class OrderForm(ModelForm):
    class Meta:
        model = Order

    def clean_shipping_street(self):
        print "JUST GET ME SOME OUTPUT!!!"
        raise forms.ValidationError('RAWRAWR')
以下是我的测试方法:

def checkout(request):
    of = OrderForm()
    if request.method == "POST":
        of = OrderForm(request.POST)
        print 'Form valid:', of.is_valid()

    # ...
    # return my HttpResponse with 'of' in the context.

我不确定我是否只是一个clutz,但以下方法奏效了(并回答了我的全部问题):

类订单(模型表单): 类元: 型号=订单

def clean_shipping_street(self):
    print 'VALIDATING!!! YEY!'
    if self.cleaned_data['ship_to_billing']:
        return self.clean_billing_street()
    return super(OrderForm, self).clean_shipping_street()
但是如果你认为我走错了方向,请告诉我

正如Nick在下面指出的那样,已清理的\u数据不是在保证订单中填写的,这意味着当调用
clean\u shipping\u street()
时,
发货到\u账单可能不存在。解决方法是调用
clean\u shipping\u street()
方法,而不是访问
clean\u数据

def clean_shipping_street(self):
    print 'VALIDATING!!! YEY!'
    if self.clean_ship_to_billing():
        return self.clean_billing_street()
    return super(OrderForm, self).clean_shipping_street()
如果您不像我编写代码时那样懒惰,那么您可能希望避免对布尔字段进行如此多的重复验证。这应该更快(前提是除非需要,否则不会运行默认字段-我自己也不确定):

甚至比这更好:

def clean_shipping_street(self):
    if not self.cleaned_data.has_key['ship_to_billing']:
        self.cleaned_data['ship_to_billing'] = self.clean_ship_to_billing()
    if self.cleaned_data['ship_to_billing']:
        return self.clean_billing_street()
    return super(OrderForm, self).clean_shipping_street()

这只是略有不同,但它应该意味着clean_ship_to_billing()的调用要比我以前的工作少得多。但说真的,我怀疑你甚至不能在分析会话中检测到这些“改进”。

我的上一个回答有几个问题。复制的数据没有返回到表单中(可能是您想要的,我需要),而且有点不可靠

这是我现在使用的。我没有添加几十个
clean_field_name()
定义,而是在
BooleanField
上添加了一个:

def clean_ship_to_billing(self):
    if self.cleaned_data.get('ship_to_billing', False):
        data = self.data.copy()
        for f in ['street', 'street_2', 'post_code', 'city', 'county', 'country', ]:
            data['shipping_%s' % f] = data['billing_%s' % f]
        self.data = data
如果选中,它会将帐单字段的原始数据复制到发货字段中。在模型的(或表单的)字段订单中,该字段位于装运字段之前,这一点很重要


我正在复制self.data,因为POST数据是不可变的。

这就是我要做的。可能不是最好的,但自定义清理方法可能是最简单的。请注意,
clean\u
方法不会按任何特定顺序调用,因此在上述情况下,
ship\u to\u billing
可能尚未在
cleaned\u data
中设置。一般来说,如果您的clean方法依赖于表单中的多个项目,请使用普通的
clean
方法。关于这一点,我有个主意。不是调用
self.cleaned_data['field_name']
,而是调用
self.clean_field_name()
——这样可以保证得到一个结果(除非自定义清理具有混乱的循环依赖关系)。对于CPU来说,这需要做更多的工作,但它应该一直工作。
def clean_ship_to_billing(self):
    if self.cleaned_data.get('ship_to_billing', False):
        data = self.data.copy()
        for f in ['street', 'street_2', 'post_code', 'city', 'county', 'country', ]:
            data['shipping_%s' % f] = data['billing_%s' % f]
        self.data = data