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

Django 3.0表单clean方法无法获取production_process值的问题求助

问题分析与修复方案

错误根源

  1. production_process字段QuerySet错误:该字段是ForeignKey,对应表单的ModelChoiceField要求QuerySet返回模型实例,但你用values_list("name", flat=True)返回了字符串列表,导致表单提交时,选择的工序ID无法与QuerySet中的字符串匹配,触发「无效选择」验证错误。
  2. clean方法逻辑混乱:原代码中try-except块滥用,且在未验证production_process是否存在的情况下直接调用production_process.id,会引发属性错误;重复记录检查的逻辑也存在逻辑错误。

修复步骤

1. 修正production_process字段的QuerySet

在表单__init__方法中,将QuerySet改为返回当前客户下未删除的ProductionProcess实例:

class ProductionCapacityForm(forms.ModelForm):
    date = forms.DateField(required=True, widget=forms.DateInput(attrs={
                                'class':'datepicker'
                            }))
    
    def __init__(self, *args, **kwargs):
        self.client = kwargs.pop('client')
        self.request = kwargs.pop('request')
        try:
            self.work_time = kwargs.pop('work_time')
        except KeyError:
            pass
        super(ProductionCapacityForm, self).__init__(*args, **kwargs)
        # 修正:返回ProductionProcess实例,过滤当前客户+未删除的工序
        self.fields['production_process'].queryset = ProductionProcess.objects.filter(
            client=self.client,
            is_deleted=False
        ).distinct()
        
        self.fields['date'].widget.attrs.update({
            'placeholder': 'Select Date',
            'class': 'input-class_name'
        })

2. 重构clean方法的验证逻辑

修复重复记录检查逻辑,避免属性错误:

def clean(self):
        cleaned_data = super().clean()
        production_process = cleaned_data.get('production_process')
        number_of_people = cleaned_data.get('number_of_people')
        datee = cleaned_data.get('date')
        pk = self.instance.pk

        # 仅当所有必填字段都存在时检查重复
        if production_process and datee:
            # 构建查询条件:匹配当前客户、日期、工序
            duplicate_query = ProductionCapacity.objects.filter(
                client=self.client,
                date=datee,
                production_process=production_process
            )
            # 编辑模式下排除当前实例
            if pk:
                duplicate_query = duplicate_query.exclude(pk=pk)
            # 存在重复则抛出错误
            if duplicate_query.exists():
                raise forms.ValidationError('该生产工序在当日已存在记录')
        
        # 保留字段值(原逻辑无需修改,直接返回cleaned_data即可)
        return cleaned_data

3. 补充模型依赖(若缺失)

确保ProductionProcess模型包含client外键(否则clean方法中的client=self.client会报错):

# models.py
class ProductionProcess(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    is_deleted = models.BooleanField(default=False)
    # 其他自定义字段...

修复说明

  • 修正QuerySet后,ModelChoiceField会正确渲染工序名称(默认显示模型__str__方法返回值),提交时传递的工序ID能与QuerySet中的实例匹配,解决「无效选择」错误。
  • 重构后的clean方法先调用父类clean()获取合法的cleaned_data,再进行重复检查,逻辑清晰且避免了属性错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:05:11