You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:57:45