4

我正在尝试创建一种自定义清理方法,如果一个特定数据的值已经存在并且如果是会引发错误,则该方法会在数据库中查找。我正在使用从其他类(项目)继承的类(子系统)的模型形式。当我尝试在表单中添加新系统时,我想检查系统系统是否已经存在。

我在我的视图函数中获得项目名称。

class SubsytemForm(forms.ModelForm):  

    class Meta:
        model = Subsystem
        exclude = ('project_name')

    def clean(self,project_name):

        cleaned_data = super(SubsytemForm, self).clean(self,project_name)
        form_subsystem_name = cleaned_data.get("subsystem_name")

        Subsystem.objects.filter(project__project_name=project_name)
        subsystem_objects=Subsystem.objects.filter(project__project_name=project_name)
        nb_subsystem = subsystem_objects.count()

        for i in range (nb_subsystem):
            if (subsystem_objects[i].subsystem_name==form_subsystem_name):
                msg = u"Subsystem already existing"
                self._errors["subsystem_name"] = self.error_class([msg])

            # These fields are no longer valid. Remove them from the
            # cleaned data.
            del cleaned_data["subsystem_name"]
        return cleaned_data

我的视图功能:

def addform(request,project_name):
    if form.is_valid(): 
        form=form.save(commit=False)
        form.project_id=Project.objects.get(project_name=project_name).id 
        form.clean(form,project_name)
        form.save()

这不起作用,我不知道该怎么做。我有错误:clean() 正好需要 2 个参数(1 个给定)

我的模型:

class Project(models.Model):
project_name = models.CharField("Project name", max_length=20)

Class Subsystem(models.Model):
subsystem_name = models.Charfield("Subsystem name", max_length=20)
projects = models.ForeignKey(Project)
4

2 回答 2

12

这段代码有很多问题。

首先,您不应该clean显式调用。当你调用form.is_valid(). 而且因为它是自动完成的,所以你不能传递额外的参数。您需要在实例化表单时传递参数,并将其保留为您的干净代码可以引用的实例变量。

其次,代码实际上只验证一个字段。所以应该用特定的clean_fieldname方法来完成——即clean_subsystem_name。这避免了_errors在最后处理和删除不需要的数据的需要。

第三,如果你发现自己对某事进行计数,遍历一个范围,然后使用该索引指向原始列表,那么你做错了。在 Python 中,您应该始终遍历您感兴趣的实际事物(在这种情况下为查询集)。但是,在这种情况下,无论如何这都无关紧要,因为您应该直接在数据库中查询实际名称并检查是否它存在,而不是通过检查匹配进行迭代。

所以,把它们放在一起:

class SubsytemForm(forms.ModelForm):  

    class Meta:
        model = Subsystem
        exclude = ('project_name')

    def __init__(self, *args, **kwargs):
        self.project_name = kwargs.pop('project_name', None)
        super(SubsystemForm, self).__init__(*args, **kwargs)

    def clean_subsystem_name(self):
        form_subsystem_name = self.cleaned_data.get("subsystem_name")

        existing = Subsystem.objects.filter(
                       project__project_name=self.project_name,
                       subsytem_name=form_subsystem_name
                   ).exists()

        if existing:
            raise forms.ValidationError(u"Subsystem already existing")

        return form_subsystem_name
于 2012-07-20T13:48:24.823 回答
0

当您执行 form=form.save(commit=False) 时,您将 Subsystem 实例存储在变量形式中,但 clean 方法在 SubsystemForm 中定义。不是吗?

于 2012-07-20T13:33:12.497 回答