Django模型创建时字段组互斥非空校验实现问询
Django模型创建阶段的互斥字段组校验实现
要实现“要么字段A、B、C、D全部非空,要么字段E、F、G、H全部非空”的校验规则,可通过重写模型的clean()方法完成自定义校验,具体实现如下:
1. 定义模型字段
首先定义模型,将两组字段都设置为允许空值(null=True, blank=True),适配其中一组完全为空的合法场景:
from django.db import models from django.core.exceptions import ValidationError class TargetModel(models.Model): # 第一组字段:A、B、C、D field_a = models.CharField(max_length=100, null=True, blank=True) field_b = models.CharField(max_length=100, null=True, blank=True) field_c = models.CharField(max_length=100, null=True, blank=True) field_d = models.CharField(max_length=100, null=True, blank=True) # 第二组字段:E、F、G、H field_e = models.CharField(max_length=100, null=True, blank=True) field_f = models.CharField(max_length=100, null=True, blank=True) field_g = models.CharField(max_length=100, null=True, blank=True) field_h = models.CharField(max_length=100, null=True, blank=True)
2. 重写clean()方法实现校验逻辑
在模型类中重写clean()方法,添加自定义校验规则:
def clean(self): super().clean() # 分组定义字段值及对应名称 group1_values = [self.field_a, self.field_b, self.field_c, self.field_d] group1_names = ['A', 'B', 'C', 'D'] group2_values = [self.field_e, self.field_f, self.field_g, self.field_h] group2_names = ['E', 'F', 'G', 'H'] # 判断两组字段的填充状态 group1_all_filled = all(val is not None and val.strip() != '' for val in group1_values) group1_all_empty = all(val is None or val.strip() == '' for val in group1_values) group2_all_filled = all(val is not None and val.strip() != '' for val in group2_values) group2_all_empty = all(val is None or val.strip() == '' for val in group2_values) # 校验合法场景:第一组全填且第二组全空,或第二组全填且第一组全空 if (group1_all_filled and group2_all_empty) or (group2_all_filled and group1_all_empty): return # 校验不合法场景,抛出对应错误 if not group1_all_empty and not group1_all_filled: # 第一组部分为空,找出空字段并提示 empty_fields = [name for name, val in zip(group1_names, group1_values) if val is None or val.strip() == ''] for field in empty_fields: raise ValidationError(f"错误:条件1下字段{field}不能为空") elif not group2_all_empty and not group2_all_filled: # 第二组部分为空,找出空字段并提示 empty_fields = [name for name, val in zip(group2_names, group2_values) if val is None or val.strip() == ''] for field in empty_fields: raise ValidationError(f"错误:条件2下字段{field}不能为空") else: # 两组都填或都空的情况 raise ValidationError("错误:必须填写字段A、B、C、D全部内容,或者填写字段E、F、G、H全部内容")
3. 校验效果说明
- 合法输入:仅填写A、B、C、D且全非空,或仅填写E、F、G、H且全非空,校验通过。
- 非法输入示例:填写A、C、D但B为空时,会抛出错误提示:
错误:条件1下字段B不能为空。 - 其他非法场景(如两组都填、两组都空),会抛出对应的统一错误提示。
内容的提问来源于stack exchange,提问作者Montio5
相关产品推荐
相关产品推荐

