Django视图计算过滤数据时验证值及单位一致性的实现问题
解决方案
1. 'float' object is not callable报错原因
你将验证器直接通过括号追加到聚合返回的浮点数值后调用,这是完全错误的用法:验证器是独立的校验函数,需要主动把待校验的值作为参数传入执行,而不是作为数值的调用方法。
2. 修正值校验逻辑(处理0/None问题)
首先完善校验函数,补充None值判断:
# validators.py from django.core.exceptions import ValidationError from django.utils.translation import gettext as _ def validate_calc_value(value): if value is None or value == 0: raise ValidationError( _('存在为0或空的计算参数,无法执行计算'), code='invalid_value' )
校验函数的正确调用方式是直接传参执行,你可以通过捕获异常将错误信息友好返回给前端,避免服务端直接报错。
3. 新增单位一致性校验逻辑
先查询筛选后所有关联的UsedXduct记录的单位,去重后判断是否只有唯一单位,否则返回警告。
4. 完整修正后的视图代码
# views.py from django.core.exceptions import ValidationError from django.db.models import Sum, Q from .validators import validate_calc_value from .models import UsedXduct def process_mass_intensity(request): plants = Plant.objects.all() myFilter = PlantsNameFilter(request.GET, queryset=plants) plants = myFilter.qs context = {"plants": plants, "myFilter": myFilter, "error": None, "warning": None, "pmi": None} # 先校验单位一致性 used_units = UsedXduct.objects.filter(plant__in=plants).values_list('unit__id', flat=True).distinct() if len(used_units) > 1: context['warning'] = '所选数据包含多种不同单位,仅单位完全一致时可执行计算' return render(request, 'kpi/process_mass_intensity.html', context) # 执行聚合计算 total_m = plants.aggregate(Sum('used_in_plant__value'))['used_in_plant__value__sum'] product_m = plants.aggregate( product_mass=Sum('used_in_plant__value', filter=Q(used_in_plant__input_or_output='OUT')) )['product_mass'] # 校验计算参数 try: validate_calc_value(total_m) validate_calc_value(product_m) pmi = total_m / product_m context['pmi'] = round(pmi, 2) context['total_m'] = total_m context['product_m'] = product_m except ValidationError as e: context['error'] = e.message return render(request, 'kpi/process_mass_intensity.html', context)
5. 模板提示示例
你可以在模板中添加以下代码展示错误和警告信息:
{% if error %} <div class="alert alert-danger">{{ error }}</div> {% endif %} {% if warning %} <div class="alert alert-warning">{{ warning }}</div> {% endif %} {% if pmi %} <div class="alert alert-success">计算结果:PMI = {{ pmi }}</div> {% endif %}
内容的提问来源于stack exchange,提问作者piah
相关产品推荐
相关产品推荐

