4

1 つの特定のデータの値が既に存在し、存在する場合はエラーが発生する場合にデータベースを調べるカスタム クリーニング メソッドを作成しようとしています。他のクラス (プロジェクト) から継承しているクラス (サブシステム) のモデル形式を使用しています。フォームに新しいシステムを追加しようとしたときに、sybsystem が既に存在するかどうかを確認したいと考えています。

ビュー関数でプロジェクト名を取得します。

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まず、明示的に呼び出すことは想定されていません。を呼び出すと、Django が自動的に実行しますform.is_valid()。また、これは自動的に行われるため、余分な引数を渡すことはできません。フォームをインスタンス化するときに引数を渡し、きれいなコードが参照できるインスタンス変数として保持する必要があります。

次に、コードは実際には 1 つのフィールドのみを検証しています。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 インスタンスが変数フォームに格納されますが、クリーン メソッドは SubsystemForm で定義されます。ではない?

于 2012-07-20T13:33:12.497 に答える