管理変更フォーム内のインラインフォームセット全体を強制的に作成したいと考えています。私の現在のシナリオでは、インボイスフォーム(管理者)の保存を押すと、インラインオーダーフォームは空白になります。私は、注文を伴わない請求書の作成を止めたいと思っています。Djangoのインラインフォーム検証
誰でも簡単な方法を知っていますか?
モデルフィールドの(required=True
)のような通常の検証は、このインスタンスでは動作しないように見えます。
管理変更フォーム内のインラインフォームセット全体を強制的に作成したいと考えています。私の現在のシナリオでは、インボイスフォーム(管理者)の保存を押すと、インラインオーダーフォームは空白になります。私は、注文を伴わない請求書の作成を止めたいと思っています。Djangoのインラインフォーム検証
誰でも簡単な方法を知っていますか?
モデルフィールドの(required=True
)のような通常の検証は、このインスタンスでは動作しないように見えます。
少なくとも1つの請求書オーダーが存在することを検証するクリーンメソッドを使用してカスタムフォームセットを定義することをお勧めします。
class InvoiceOrderInlineFormset(forms.models.BaseInlineFormSet):
def clean(self):
# get forms that actually have valid data
count = 0
for form in self.forms:
try:
if form.cleaned_data:
count += 1
except AttributeError:
# annoyingly, if a subform is invalid Django explicity raises
# an AttributeError for cleaned_data
pass
if count < 1:
raise forms.ValidationError('You must have at least one order')
class InvoiceOrderInline(admin.StackedInline):
formset = InvoiceOrderInlineFormset
class InvoiceAdmin(admin.ModelAdmin):
inlines = [InvoiceOrderInline]
ダニエルの答えは優れており、それは一つのプロジェクトに私のために働いたが、その後、私は原因Djangoは仕事を形成する方法に実現し、あなたがcan_deleteを使用し、節約しながら削除]チェックボックスをオンにしている場合、それはワットを検証することが可能です/ o任意の注文(この場合)。
私はしばらく時間を費やして、そのことを防ぐ方法を見つけようとしました。最初の状況は簡単でした。カウントで削除されるフォームは含めないでください。 2番目の状況がより手っ取り早い... すべて削除ボックスがチェックされている場合、clean
は呼び出されていませんでした。
コードは、残念ながら、まったく簡単なものではありません。 clean
メソッドは、error
プロパティにアクセスするときに呼び出されるfull_clean
から呼び出されます。このプロパティは、サブフォームが削除されているときにはアクセスされないため、full_clean
は呼び出されません。私はDjangoの専門家ではないので、これは恐ろしい方法かもしれませんが、うまくいくようです。
ここで修正クラスです:
class InvoiceOrderInlineFormset(forms.models.BaseInlineFormSet):
def is_valid(self):
return super(InvoiceOrderInlineFormset, self).is_valid() and \
not any([bool(e) for e in self.errors])
def clean(self):
# get forms that actually have valid data
count = 0
for form in self.forms:
try:
if form.cleaned_data and not form.cleaned_data.get('DELETE', False):
count += 1
except AttributeError:
# annoyingly, if a subform is invalid Django explicity raises
# an AttributeError for cleaned_data
pass
if count < 1:
raise forms.ValidationError('You must have at least one order')
class MandatoryInlineFormSet(BaseInlineFormSet):
def is_valid(self):
return super(MandatoryInlineFormSet, self).is_valid() and \
not any([bool(e) for e in self.errors])
def clean(self):
# get forms that actually have valid data
count = 0
for form in self.forms:
try:
if form.cleaned_data and not form.cleaned_data.get('DELETE', False):
count += 1
except AttributeError:
# annoyingly, if a subform is invalid Django explicity raises
# an AttributeError for cleaned_data
pass
if count < 1:
raise forms.ValidationError('You must have at least one of these.')
class MandatoryTabularInline(admin.TabularInline):
formset = MandatoryInlineFormSet
class MandatoryStackedInline(admin.StackedInline):
formset = MandatoryInlineFormSet
class CommentInlineFormSet(MandatoryInlineFormSet):
def clean_rating(self,form):
"""
rating must be 0..5 by .5 increments
"""
rating = float(form.cleaned_data['rating'])
if rating < 0 or rating > 5:
raise ValidationError("rating must be between 0-5")
if (rating/0.5) != int(rating/0.5):
raise ValidationError("rating must have .0 or .5 decimal")
def clean(self):
super(CommentInlineFormSet, self).clean()
for form in self.forms:
self.clean_rating(form)
class CommentInline(MandatoryTabularInline):
formset = CommentInlineFormSet
model = Comment
extra = 1
で働くことです余分な= 0で同じことをすることが可能ですか? –
@シヴァ - 私はちょうどチェックした、そして余分な= 0を持つことができます。しかし、コメントを(私の場合は)必須にするには、ユーザーに空白のフォームを指定するか、必須にしないでください。 – Kurt
完璧なソリューションをこれを試してみてください、ありがとう – user108791
私は削除ボックスがチェックされている場合、それは0注文で検証することも可能だということが分かりました。その問題を解決する改訂されたクラスの私の答えを参照してください。 –
この修正プログラム(および強化のためのDan)に感謝します。 私は 'MandatoryInlineFormSet(BaseInlineFormSet)'クラスを作成し、それからInvoiceAdminFormSetを導き出しました。 InvoiceAdminFormSetには、カスタム検証を行うclean()メソッドがありますが、最初にMandatoryInlineFromSet.clean()にコールバックします。 – Kurt