django manytomany验证

时间:2010-10-04 08:29:03

标签: django validation model-validation

请参阅下面的代码。基本上,当用户创建此类的对象时,他们需要指定value_type。如果value_type==2(百分比),则percentage_calculated_on(表单/模板一侧的CheckboxSelectMultiple需要检查一个或多个项目。模型验证不允许我像我一样验证尝试 - 它基本上抛出一个异常,告诉我实例需要在使用多对多关系之前有一个主键值。但是我需要先保存对象然后保存它。我试过这个在表单(modelform)方面进行验证(使用表单的clean方法),但同样的事情也发生在那里。

如何实现此验证?

INHERENT_TYPE_CHOICES = ((1, 'Payable'), (2, 'Deductible'))
VALUE_TYPE_CHOICES = ((1, 'Amount'), (2, 'Percentage'))

class Payable(models.Model):
    name = models.CharField()
    short_name = models.CharField()
    inherent_type = models.PositiveSmallIntegerField(choices=INHERENT_TYPE_CHOICES)
    value = models.DecimalField(max_digits=12,decimal_places=2)
    value_type = models.PositiveSmallIntegerField(choices=VALUE_TYPE_CHOICES)
    percentage_calculated_on = models.ManyToManyField('self', symmetrical=False)

    def clean(self):
        from django.core.exceptions import ValidationError
        if self.value_type == 2 and not self.percentage_calculated_on:
            raise ValidationError("If this is a percentage, please specify on what payables/deductibles this percentage should be calculated on.")

1 个答案:

答案 0 :(得分:2)

我在我的一个项目管理应用中测试了你的代码。我可以使用自定义ModelForm执行您需要的验证。见下文。

# forms.py
class MyPayableForm(forms.ModelForm):
    class Meta:
        model = Payable

    def clean(self):
        super(MyPayableForm, self).clean() # Thanks, @chefsmart
        value_type = self.cleaned_data.get('value_type', None)
        percentage_calculated_on = self.cleaned_data.get(
             'percentage_calculated_on', None)
        if value_type == 2 and not percentage_calculated_on:
            message = "Please specify on what payables/deductibles ..."
            raise forms.ValidationError(message)
        return self.cleaned_data

# admin.py
class PayableAdmin(admin.ModelAdmin):
    form = MyPayableForm

admin.site.register(Payable, PayableAdmin)

管理员应用使用SelectMultiple窗口小部件(而不是CheckboxSelectMultiple)来表示多对多关系。我相信这应该不重要。