Daniels Antwort ist ausgezeichnet und es funktionierte an einem Projekt für mich, aber dann merkte ich, aufgrund der Art und Weise Django Arbeit bildet, wenn Sie can_delete und überprüfen Sie die Lösch Box verwenden beim Speichern, ist es möglich, w zu validieren/o irgendwelche Bestellungen (in diesem Fall).
Ich verbrachte eine Weile damit herauszufinden, wie man das verhindern kann. Die erste Situation war einfach - schließen Sie nicht die Formulare ein, die bei der Zählung gelöscht werden. Die zweite Situation war kniffliger ... Wenn alle die Löschfelder überprüft werden, dann wurde clean
nicht aufgerufen.
Der Code ist leider nicht gerade geradlinig. Die clean
-Methode wird von full_clean
aufgerufen, die aufgerufen wird, wenn auf die error
-Eigenschaft zugegriffen wird. Auf diese Eigenschaft wird nicht zugegriffen, wenn ein Teilformular gelöscht wird. Daher wird full_clean
niemals aufgerufen. Ich bin kein Django-Experte, also könnte das ein schrecklicher Weg sein, aber es scheint zu funktionieren.
Hier ist die modifizierte Klasse:
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')
Perfekte Lösung, dank – user108791
Ich fand, dass, wenn das Löschfeld aktiviert ist, es möglich ist, mit 0 Aufträgen zu validieren. Sehen Sie meine Antwort für eine überarbeitete Klasse, die das Problem löst. –
Vielen Dank für dieses Update (und Dan für die Verbesserung). Als möglicher Hinweis für andere habe ich eine 'Klasse MandatoryInlineFormSet (BaseInlineFormSet)' und dann InvoiceAdminFormSet daraus abgeleitet. In meinem InvoiceAdminFormSet habe ich eine clean() -Methode, die eine benutzerdefinierte Validierung durchführt, aber zuerst zu MandatoryInlineFromSet.clean() zurückruft. – Kurt