【问题标题】:Django unexpectedly sets a field to None when validating a formset验证表单集时,Django 意外将字段设置为 None
【发布时间】:2012-07-31 08:21:11
【问题描述】:

我在使用 django 时遇到了一个奇怪的问题。似乎当我在表单集上运行 is_valid() 时,每个子表单的一个值设置为无。为了检查这一点,我放了两条调试线来打印cleaned_data dict。一个在cleaned_qty() 的末尾,另一个在is_valid() 之后。

这是表格:

class ProductsForm(forms.Form):
    product_ref     = forms.CharField(max_length=6, widget=forms.HiddenInput)
    product_name    = forms.CharField(max_length=200, widget=forms.HiddenInput)
    unit            = forms.CharField(max_length=16, widget=forms.HiddenInput)
    qty             = forms.DecimalField(max_digits=6, decimal_places=3,
                        widget=forms.TextInput(attrs={'size': 5}))

    def clean_qty(self):
        data = self.cleaned_data

        if data['qty'] < 0:
            raise ValidationError('La quantité doit être positive')

        unit = Unit.objects.get(pk=data['unit'])

        if not unit.accept_dec and '.' in str(data['qty']) \
        and int(str(data['qty']).split('.')[1]) != 0:
            raise ValidationError('La quantité doit être entière')

        print "!!!" + str(data) + "!!!"

ProductsFormSet = formsets.formset_factory(ProductsForm, extra=0,
    can_delete=True)

这是视图的开始:

def cart(request):
    if request.method == 'POST':
        products_formset = ProductsFormSet(request.POST, prefix='products')
        cart_form = CartForm(request.POST, prefix='cart')
        if products_formset.is_valid() and cart_form.is_valid():
            '''
                Create and save the cart
                Send a confirmation email
            '''

            for form in products_formset:
                print "???" + str(form.cleaned_data) + "???"

当我提交表单时的结果:

DEBUG:django.db.backends:(0.000) SELECT `catalog_unit`.`value`, `catalog_unit`.`plural_val`, `catalog_unit`.`accept_dec` FROM `catalog_unit` WHERE `catalog_unit`.`value` = 'Truc' ; args=(u'Truc',)
!!!{'product_ref': u'BDL233', 'product_name': u'Bidule', 'unit': u'Truc', 'qty': Decimal('2.2')}!!!
DEBUG:django.db.backends:(0.001) SELECT `catalog_unit`.`value`, `catalog_unit`.`plural_val`, `catalog_unit`.`accept_dec` FROM `catalog_unit` WHERE `catalog_unit`.`value` = 'Truc' ; args=(u'Truc',)
!!!{'product_ref': u'MCH024', 'product_name': u'Machin', 'unit': u'Truc', 'qty': Decimal('1.3')}!!!
DEBUG:django.db.backends:(0.000) SELECT `catalog_unit`.`value`, `catalog_unit`.`plural_val`, `catalog_unit`.`accept_dec` FROM `catalog_unit` WHERE `catalog_unit`.`value` = 'Chacal' ; args=(u'Chacal',)
!!!{'product_ref': u'CHO127', 'product_name': u'Chouette', 'unit': u'Chacal', 'qty': Decimal('3')}!!!
???{'DELETE': False, 'product_ref': u'BDL233', 'product_name': u'Bidule', 'unit': u'Truc', 'qty': None}???
???{'DELETE': False, 'product_ref': u'MCH024', 'product_name': u'Machin', 'unit': u'Truc', 'qty': None}???
???{'DELETE': False, 'product_ref': u'CHO127', 'product_name': u'Chouette', 'unit': u'Chacal', 'qty': None}???

如您所见,唯一的区别是 qty 设置为 None。

我不知道这种行为是从哪里来的。

提前感谢您的光。

【问题讨论】:

标签: python django django-forms undefined-behavior django-validation


【解决方案1】:

所有clean_FIELD 方法必须返回正在验证的值。所以你的clean_qty 方法应该有return data['qty']

【讨论】:

    猜你喜欢
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2015-10-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    相关资源
    最近更新 更多