Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python BaseModelFormset中自定义clean()方法的KeyError_Python_Django_Django Models_Django Forms - Fatal编程技术网

Python BaseModelFormset中自定义clean()方法的KeyError

Python BaseModelFormset中自定义clean()方法的KeyError,python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我已经阅读了大约100x的表单和表单集Django文档。为了说明这一点,这可能是我第一次使用super()或试图重载/继承另一个类(对我来说很重要) 发生了什么事?我在视图中创建django模型表单集,并将其传递给模板。表单集从中继承的模型恰好是一个多个关系。我希望这些关系是唯一的,因此,如果我的用户正在创建表单,并且他们意外地为多个对象选择了相同的对象,我希望它无法通过验证 我相信我已经正确地编写了这个定制的“BaseModelFormSet”(通过文档),但是我得到了一个关键错误。它告诉我它

我已经阅读了大约100x的表单和表单集Django文档。为了说明这一点,这可能是我第一次使用super()或试图重载/继承另一个类(对我来说很重要)

发生了什么事?我在视图中创建django模型表单集,并将其传递给模板。表单集从中继承的模型恰好是一个多个关系。我希望这些关系是唯一的,因此,如果我的用户正在创建表单,并且他们意外地为多个对象选择了相同的对象,我希望它无法通过验证

我相信我已经正确地编写了这个定制的“BaseModelFormSet”(通过文档),但是我得到了一个关键错误。它告诉我它找不到清理过的_数据['tech'],我在下面的评论中得到了单词'tech'上的关键错误

模型:

class Tech_Onsite(models.Model):
    tech = models.ForeignKey(User)
    ticket = models.ForeignKey(Ticket)
    in_time = models.DateTimeField(blank=False)
    out_time = models.DateTimeField(blank=False)

    def total_time(self):
        return self.out_time - self.in_time
自定义的BaseModelFormSet:

from django.forms.models import BaseModelFormSet
from django.core.exceptions import ValidationError

class BaseTechOnsiteFormset(BaseModelFormSet):
    def clean(self):

        """ Checks to make sure there are unique techs present """

        super(BaseTechOnsiteFormset, self).clean()

        if any(self.errors):
            # Don't bother validating enless the rest of the form is valid
            return

        techs_present = []

        for form in self.forms:
            tech = form.cleaned_data['tech']  ## KeyError: 'tech' <- 

            if tech in techs_present:
                raise ValidationError("You cannot input multiple times for the same technician.  Please make sure you did not select the same technician twice.")
            techs_present.append(tech)

clean方法不缺少return语句吗?如果我没记错的话,它应该总是返回清理过的数据。此外,super调用将返回已清理的_数据,因此您应该将其分配到那里

def clean(self):
    cleaned_data = super(BaseTechOnsiteFormset, self).clean()
    # use cleaned_data from here to validate your form
    return cleaned_data

请参阅:有关更多信息,我使用Django shell手动调用表单。我发现我正在对视图返回的所有表单执行clean()方法。其中2人填写数据,2人空白。当我的clean()方法遍历它们时,当它到达第一个空白值时,返回了一个KeyError


我通过使用try语句并传递KeyErrors解决了我的问题。

为什么不将form.u数据打印到日志输出中,然后查看有哪些键?你确定你的表单上有一个
tech
字段,它叫这个吗?@jozzas,我想这么做,但将所有表单转换成字典,然后传递到表单中,并模拟所有这些过程,这将是一个阻力。但是,我做了,发现我一共有4张表格,其中2张是空白的。当我在那些空白表单上反复搜索“tech”时,它引发了一个关键错误。谢谢你鼓励我,这很有道理。我假设它在函数中设置self.u数据,而不是返回它。我遵循了这个例子,他们没有按照你的建议去做。我认为它对表单集的工作方式可能会有所不同?
def clean(self):
    cleaned_data = super(BaseTechOnsiteFormset, self).clean()
    # use cleaned_data from here to validate your form
    return cleaned_data