Django 多对多验证

发布于 2024-09-26 10:50:55 字数 1165 浏览 3 评论 0原文

请参阅下面的代码。基本上,当用户创建此类的对象时,他们需要指定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.")

Please see the code below. Basically, when the user creates an object of this class, they need to specify the value_type. If value_type==2 (percentage), then percentage_calculated_on (which is a CheckboxSelectMultiple on the form/template side needs to have one or more items checked. The model validation isn't allowing me to validate like I'm trying to -- it basically throws an exception that tells me that the instance needs to have a primary key value before a many-to-many relationship can be used. But I need to first validate the object before saving it. I have tried this validation on the form (modelform) side (using the form's clean method), but the same thing happens there too.

How do I go about achieving this validation?

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.")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

﹉夏雨初晴づ 2024-10-03 10:50:55

我在我的一个项目的管理应用程序中测试了您的代码。我能够使用自定义 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)来表示多对多关系。我相信这应该不重要。

I tested out your code in one of my projects' admin app. I was able to perform the validation you required by using a custom ModelForm. See below.

# 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)

The Admin app uses the SelectMultiple widget (rather than CheckboxSelectMultiple as you do) to represent many to many relationships. I believe this shouldn't matter though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文