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

如何统计Django模型空字段并在命令中计算填充进度?

实现自动统计字段填充进度的方案

1. 封装自动计算进度的模型方法

直接在Iniciativa模型中添加方法,利用Django模型的_meta属性自动遍历字段,无需手动逐个指定检查项:

class Iniciativa(models.Model):
    iniciativa      = models.CharField(max_length=150)
    canal           = models.ForeignKey(Canales, blank=True, null=True, on_delete=models.CASCADE)
    territorio      = models.JSONField(default=list, blank=True, null=True)
    bigbet          = models.ForeignKey(BigBet, blank=True, null=True, on_delete=models.CASCADE)
    objetivo        = models.TextField(blank=True, null=True)
    call2action     = models.TextField(blank=True, null=True)
    dialogo_valor   = models.TextField(blank=True, null=True)
    cobertura       = models.TextField(blank=True, null=True)
    kpi_medicion    = models.TextField(blank=True, null=True)

    def get_completion_percentage(self):
        # 筛选出需要检查的字段:排除自动生成字段、反向关联字段
        target_fields = [
            field for field in self._meta.get_fields()
            if not field.auto_created and not field.one_to_many and not field.one_to_one
        ]
        total_fields = len(target_fields)
        if total_fields == 0:
            return 0
        
        filled_count = 0
        for field in target_fields:
            field_value = getattr(self, field.name)
            
            # 根据字段类型判断是否为有效填充值
            if field.null and field_value is None:
                continue
            if isinstance(field, (models.CharField, models.TextField)):
                if field_value.strip():  # 排除空字符串或纯空格
                    filled_count += 1
            elif isinstance(field, models.ForeignKey):
                if field_value is not None:
                    filled_count += 1
            elif isinstance(field, models.JSONField):
                # 排除空列表,判断是否为有效JSON内容
                if field_value and not (isinstance(field_value, list) and len(field_value) == 0):
                    filled_count += 1
            else:
                # 其他字段类型直接判断非空
                if field_value is not None:
                    filled_count += 1
        
        # 计算并返回百分比(保留整数)
        return round((filled_count / total_fields) * 100)

2. 在自定义导入命令中调用方法

在导入数据的自定义命令里,每处理一条数据就调用进度计算方法,输出或存储进度:

from django.core.management.base import BaseCommand
from your_app.models import Iniciativa

class Command(BaseCommand):
    help = '导入数据并统计字段填充进度'

    def handle(self, *args, **options):
        # 模拟从文件读取的原始数据
        import_dataset = [...]  # 替换为你的文件数据读取逻辑
        
        total_records = len(import_dataset)
        for idx, data_item in enumerate(import_dataset):
            # 创建或更新数据库实例
            iniciativa, _ = Iniciativa.objects.get_or_create(
                iniciativa=data_item['iniciativa'],
                defaults={
                    'canal': data_item.get('canal'),
                    'territorio': data_item.get('territorio'),
                    'bigbet': data_item.get('bigbet'),
                    'objetivo': data_item.get('objetivo'),
                    'call2action': data_item.get('call2action'),
                    'dialogo_valor': data_item.get('dialogo_valor'),
                    'cobertura': data_item.get('cobertura'),
                    'kpi_medicion': data_item.get('kpi_medicion'),
                }
            )
            # 获取当前实例的填充进度
            completion_rate = iniciativa.get_completion_percentage()
            # 输出进度到控制台,前端可监听控制台输出或写入临时文件供读取
            self.stdout.write(
                f"已处理 {idx+1}/{total_records} 条数据 | 当前实例填充进度:{completion_rate}%"
            )

3. 可选:持久化进度到数据库

如果需要前端通过API直接获取进度,可以给模型添加存储字段,在保存时自动更新:

class Iniciativa(models.Model):
    # 原有字段...
    completion_percent = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        # 保存前自动计算并更新进度
        self.completion_percent = self.get_completion_percentage()
        super().save(*args, **kwargs)

内容的提问来源于stack exchange,提问作者Leonardo Esquivel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:14:55