Django Admin如何实现PurchaseItem模型两个外键二选一必填校验
Django Admin 实现PurchaseItem模型校验的方案
方案1:模型层全局校验(推荐)
该方案的校验规则会作用于所有数据保存场景,包括Admin后台、API接口、shell操作等,避免校验规则遗漏。
修改你的PurchaseItem模型代码如下:
from django.db import models from django.core.exceptions import ValidationError class PurchaseItem(models.Model): product = models.ForeignKey("products.Product", on_delete=models.CASCADE, blank=True, null=True) product_attribute = models.ForeignKey("products.ProductAttribute", on_delete=models.CASCADE, blank=True, null=True) def clean(self): # 校验两个字段不能同时不为空 if self.product_id and self.product_attribute_id: raise ValidationError("产品和产品属性不能同时选择,请只保留其中一项") # 校验两个字段不能同时为空 if not self.product_id and not self.product_attribute_id: raise ValidationError("请选择产品或者产品属性中的一项") # 执行父类默认校验逻辑 super().clean()
添加上述代码后无需额外修改Admin配置,Admin后台保存数据时会自动触发该校验,校验不通过时会直接在表单页展示错误提示。
注意:如果你在Admin之外的场景手动调用模型
save()方法,需要先执行obj.full_clean()才会触发该校验逻辑。
方案2:仅Admin层校验
如果你的校验规则只需要在Admin后台生效,可以直接在对应的ModelAdmin中重写校验方法:
from django.contrib import admin from django.core.exceptions import ValidationError from .models import PurchaseItem class PurchaseItemAdmin(admin.ModelAdmin): def clean_form(self, request, form, change): cleaned_data = form.cleaned_data product = cleaned_data.get("product") product_attribute = cleaned_data.get("product_attribute") if product and product_attribute: raise ValidationError("产品和产品属性不能同时选择,请只保留其中一项") if not product and not product_attribute: raise ValidationError("请选择产品或者产品属性中的一项") return super().clean_form(request, form, change) admin.site.register(PurchaseItem, PurchaseItemAdmin)
该方案的校验逻辑仅在Admin后台提交表单时触发,其他数据保存场景不会生效。
内容的提问来源于stack exchange,提问作者aimenanep
相关产品推荐
相关产品推荐

