4

データベースにクライアント レコードのリストがあります。毎年、クライアントごとに 1 つの作業指示書を作成します。次に、作業指示書レコードごとに、ユーザーは作業指示書に固有のメモを作成できる必要があります。ただし、すべての作業指示書にメモが必要なわけではありません。

note作業指示書が生成される前にメモを作成する必要がある場合があるため、単純に作業指示書にフィールドを追加することはできません。このメモは、2 ~ 3 年間発生しない作業指示書に固有のものである場合があります。したがって、メモと作業指示書は独立している必要がありますが、両方が存在する場合は互いに「検出」されます。

よし、これが状況だ。ユーザーが と の 2 つのフィールドを持つ非常に単純なフォームに入力できるようにしたいと考えていnoteます。したがって、彼らは年を選んでメモを書くだけです。キッカーは、ユーザーが同じクライアントに対して同じ年に 2 つのメモを作成できないようにすることです。noteYearnote

私が取得しようとしているのは、そのクライアントのその年のメモがまだないことを確認して、メモを検証することです。is_validこれは、フォーム内のカスタム メソッドによって達成されると想定していますが、それを行う方法がわかりません。

これは私がこれまでに試したことです(間違っていることはわかっていますが、うまくいきませんが、これまでのところ私の試みです):

systemID私の顧客記録であることに注意してください

私のモデル:

class su_note(models.Model):
    YEAR_CHOICES = (
        ('2013', 2013),        
        ('2014', 2014),        
        ('2015', 2015),        
        ('2016', 2016),        
        ('2017', 2017),        
        ('2018', 2018),        
        ('2019', 2019),        
        ('2020', 2020),        
        ('2021', 2021),        
        ('2022', 2022),        
        ('2023', 2023),        
    )
    noteYear = models.CharField(choices = YEAR_CHOICES, max_length = 4, verbose_name = 'Relevant Year')
    systemID = models.ForeignKey(System, verbose_name = 'System ID')
    note = models.TextField(verbose_name = "Note")

    def __unicode__(self):
        return u'%s | %s | %s' % (self.systemID.systemID, self.noteYear, self.noteType)

そして私のフォーム:

class SU_Note_Form(ModelForm):
    class Meta:
        model = su_note
        fields = ('noteYear', 'noteType', 'note')
    def is_valid(self):
        valid = super (SU_Note_Form, self).is_valid()

        #If it is not valid, we're done -- send it back to the user to correct errors
        if not valid:
            return valid

        # now to check that there is only one record of SU for the system
        sysID = self.cleaned_data['systemID']
        sysID = sysID.systemID
        snotes = su_note.objects.filter(noteYear = self.cleaned_data['noteYear'])
        for s in snotes:
            if s.systemID == self.systemID:
                self._errors['Validation_Error'] = 'There is already a startup note for this year'
                return False
        return True

編集-これが私の解決策です(正しい方向に私を送ってくれたjanosに感謝します)

私の最終的なフォームは次のようになります。

class SU_Note_Form(ModelForm):
    class Meta:
        model = su_note
        fields = ('systemID', 'noteYear', 'noteType', 'note')
    def clean(self):
        cleaned_data = super(SU_Note_Form, self).clean()
        sysID = cleaned_data['systemID']
        sysID = sysID.systemID
        try:
            s = su_note.objects.get(noteYear = cleaned_data['noteYear'], systemID__systemID = sysID)
            print(s)
            self.errors['noteYear'] = "There is already a note for this year."
        except:
            pass
        return cleaned_data        

このコードを見ている他の人にとって、唯一の紛らわしい部分は次の行です: sysID = sysID.systemID. はsystemID、実際には別のモデルsystemIDのフィールドです。このモデルのフィールドでもありますが、おそらく設計が不十分ですが、機能します。

4

1 に答える 1

5

Django ドキュメントのこのページを参照してください: https://docs.djangoproject.com/en/dev/ref/forms/validation/

検証ロジックは 2 つのフィールド (年とシステム ID) に依存するため、フォームでカスタム クリーニング メソッドを使用してこれを実装する必要があります。次に例を示します。

def clean(self):
    cleaned_data = super(SU_Note_Form, self).clean()
    sysID = cleaned_data['systemID']
    sysID = sysID.systemID
    try:
        su_note.objects.get(noteYear=cleaned_data['noteYear'], systemID=systemID)
        raise forms.ValidationError('There is already a startup note for this year')
    except su_note.DoesNotExist:
        pass

    # Always return the full collection of cleaned data.
    return cleaned_data
于 2013-04-06T20:48:30.753 に答える