Django电力计算应用开发遇KeyError: 'transformer'问题求助
解决Django中KeyError: 'transformer'的问题
问题背景
正在开发一款基于Django的电力公式计算应用,需求是在计算页面输入变量值后,跳转至结果页面查看计算结果,需实现模块间关联以获取对应数值。开发过程中遇到KeyError: 'transformer'错误,触发位置为CalculationView的post方法中transformer = data['transformer']行。尝试修改CalculationForm的fields字段添加/移除'transformer',问题未解决。
相关代码
views.py
class CalculationView(View): def get(self, request): transformers = Transformer.objects.all() form = CalculationForm() return render(request, 'calculation_form.html', {'form': form}) def post(self, request): form = CalculationForm(request.POST) if form.is_valid(): data = form.cleaned_data LowVoltageLineCurrent = data['Power'] / (data['HighVoltage'] * math.sqrt(3)) HighVoltageLineCurrent = data['Power'] / (data['LowVoltage'] * math.sqrt(3)) if data['LVconnection'].lower() == 'y': LowVoltagePhaseCurrent = LowVoltageLineCurrent elif data['LVconnection'].lower() == 'd': LowVoltagePhaseCurrent = LowVoltageLineCurrent / math.sqrt(3) else: LowVoltagePhaseCurrent = None if data['HVconnection'].lower() == 'y': HighVoltagePhaseCurrent = HighVoltageLineCurrent elif data['HVconnection'].lower() == 'd': HighVoltagePhaseCurrent = HighVoltageLineCurrent / math.sqrt(3) else: HighVoltagePhaseCurrent = None transformer = data['transformer'] result = Result.objects.create( Power=data['Power'], HighVoltage=data['HighVoltage'], LowVoltage=data['LowVoltage'], LowVoltageLineCurrent=LowVoltageLineCurrent, HighVoltageLineCurrent=HighVoltageLineCurrent, LVconnection=data['LVconnection'], HVconnection=data['HVconnection'], LowVoltagePhaseCurrent=LowVoltagePhaseCurrent, HighVoltagePhaseCurrent=HighVoltagePhaseCurrent, transformer=transformer, user=request.user ) return redirect('results', pk=result.pk) return render(request, 'calculation_form.html', {'form': form}) class ResultsView(View): def get(self, request, pk): result = Result.objects.get(pk=pk, user=request.user) return render(request, 'results.html', {'result': result})
models.py
from django.db import models from django.utils import timezone from django.contrib.auth.models import User class Transformer(models.Model): LV_CHOICES = [('D', 'D'),('Y', 'Y'),] HV_CHOICES = [('D', 'D'),('Y', 'Y'),] user = models.ForeignKey(User, on_delete=models.PROTECT) name = models.CharField(max_length=50) Power = models.IntegerField(null=False, blank=False) HighVoltage = models.IntegerField() HVconnection = models.CharField(max_length=1, choices=HV_CHOICES, default='D', db_index=True) LowVoltage = models.IntegerField() LVconnection = models.CharField(max_length=1, choices=LV_CHOICES, default='D', db_index=True) created_at = models.DateTimeField(default=timezone.now) def __str__(self): return self.name class Result(models.Model): transformer = models.ForeignKey(Transformer, on_delete=models.CASCADE, related_name="transformer_result") HighVoltageLineCurrent = models.FloatField() HighVoltagePhaseCurrent = models.FloatField(null=True, blank=True) LowVoltageLineCurrent = models.FloatField() LowVoltagePhaseCurrent = models.FloatField()
forms.py
from django import forms from .models import Transformer class CalculationForm(forms.ModelForm): class Meta: model=Transformer fields='__all__'
错误信息
line 52, in post transformer = data['transformer'] ~~~~^^^^^^^^^^^^^^^ KeyError: 'transformer'
错误原因
CalculationForm基于Transformer模型创建,但Transformer模型本身不存在transformer字段,因此表单验证通过后,cleaned_data字典中不会有该键,直接访问会触发KeyError。- 业务逻辑需要将
Result关联到Transformer实例,但当前表单设计与需求不匹配:要么需用户选择已有变压器,要么需先创建新变压器再关联结果。
解决方案
方案一:用户选择已有变压器进行计算
若需求是让用户从已存在的变压器中选择一个,使用其参数完成计算:
- 修改forms.py,创建包含变压器选择的表单:
from django import forms from .models import Transformer class CalculationForm(forms.Form): transformer = forms.ModelChoiceField(queryset=Transformer.objects.all(), label="选择变压器") # 若需用户自定义参数,可添加对应字段,例如: # Power = forms.IntegerField(label="功率") # HighVoltage = forms.IntegerField(label="高压")
- 修改views.py的CalculationView:
class CalculationView(View): def get(self, request): form = CalculationForm() return render(request, 'calculation_form.html', {'form': form}) def post(self, request): form = CalculationForm(request.POST) if form.is_valid(): data = form.cleaned_data # 获取选中的变压器实例 transformer = data['transformer'] # 使用变压器自带参数计算 LowVoltageLineCurrent = transformer.Power / (transformer.HighVoltage * math.sqrt(3)) HighVoltageLineCurrent = transformer.Power / (transformer.LowVoltage * math.sqrt(3)) if transformer.LVconnection.lower() == 'y': LowVoltagePhaseCurrent = LowVoltageLineCurrent elif transformer.LVconnection.lower() == 'd': LowVoltagePhaseCurrent = LowVoltageLineCurrent / math.sqrt(3) else: LowVoltagePhaseCurrent = None if transformer.HVconnection.lower() == 'y': HighVoltagePhaseCurrent = HighVoltageLineCurrent elif transformer.HVconnection.lower() == 'd': HighVoltagePhaseCurrent = HighVoltageLineCurrent / math.sqrt(3) else: HighVoltagePhaseCurrent = None result = Result.objects.create( Power=transformer.Power, HighVoltage=transformer.HighVoltage, LowVoltage=transformer.LowVoltage, LowVoltageLineCurrent=LowVoltageLineCurrent, HighVoltageLineCurrent=HighVoltageLineCurrent, LVconnection=transformer.LVconnection, HVconnection=transformer.HVconnection, LowVoltagePhaseCurrent=LowVoltagePhaseCurrent, HighVoltagePhaseCurrent=HighVoltagePhaseCurrent, transformer=transformer, user=request.user ) return redirect('results', pk=result.pk) return render(request, 'calculation_form.html', {'form': form})
方案二:用户输入参数创建新变压器,再关联结果
若需求是让用户输入变压器参数,先创建新Transformer实例,再将计算结果关联到该实例:
- 修改views.py的CalculationView的post方法:
def post(self, request): form = CalculationForm(request.POST) if form.is_valid(): # 创建并保存Transformer实例 transformer = form.save(commit=False) transformer.user = request.user # 绑定当前用户 transformer.save() data = form.cleaned_data LowVoltageLineCurrent = data['Power'] / (data['HighVoltage'] * math.sqrt(3)) HighVoltageLineCurrent = data['Power'] / (data['LowVoltage'] * math.sqrt(3)) if data['LVconnection'].lower() == 'y': LowVoltagePhaseCurrent = LowVoltageLineCurrent elif data['LVconnection'].lower() == 'd': LowVoltagePhaseCurrent = LowVoltageLineCurrent / math.sqrt(3) else: LowVoltagePhaseCurrent = None if data['HVconnection'].lower() == 'y': HighVoltagePhaseCurrent = HighVoltageLineCurrent elif data['HVconnection'].lower() == 'd': HighVoltagePhaseCurrent = HighVoltageLineCurrent / math.sqrt(3) else: HighVoltagePhaseCurrent = None result = Result.objects.create( Power=data['Power'], HighVoltage=data['HighVoltage'], LowVoltage=data['LowVoltage'], LowVoltageLineCurrent=LowVoltageLineCurrent, HighVoltageLineCurrent=HighVoltageLineCurrent, LVconnection=data['LVconnection'], HVconnection=data['HVconnection'], LowVoltagePhaseCurrent=LowVoltagePhaseCurrent, HighVoltagePhaseCurrent=HighVoltagePhaseCurrent, transformer=transformer, user=request.user ) return redirect('results', pk=result.pk) return render(request, 'calculation_form.html', {'form': form})
- 修改forms.py排除user字段:
class CalculationForm(forms.ModelForm): class Meta: model=Transformer fields=['name', 'Power', 'HighVoltage', 'HVconnection', 'LowVoltage', 'LVconnection']
额外注意事项
当前Result模型缺少关联计算所需的字段,需补充:
class Result(models.Model): transformer = models.ForeignKey(Transformer, on_delete=models.CASCADE, related_name="transformer_result") Power = models.IntegerField() HighVoltage = models.IntegerField() LowVoltage = models.IntegerField() LVconnection = models.CharField(max_length=1) HVconnection = models.CharField(max_length=1) HighVoltageLineCurrent = models.FloatField() HighVoltagePhaseCurrent = models.FloatField(null=True, blank=True) LowVoltageLineCurrent = models.FloatField() LowVoltagePhaseCurrent = models.FloatField() user = models.ForeignKey(User, on_delete=models.CASCADE)
内容的提问来源于stack exchange,提问作者David D
相关产品推荐
相关产品推荐

