ich eine neue Klasse mit dem Namen ModelAdminWithInline von admin.ModelAdmin und modifizierte Methoden add_view geerbt haben (...) und change_view (...) Funktion is_cross_valid (self, Form, Formularsätze) zu nennen, Hier können Sie alle Formulare zusammen validieren. Beide Funktionen hatte:
#...
if all_valid(formsets) and form_validated:
#...
geändert:
#...
formsets_validated = all_valid(formsets)
cross_validated = self.is_cross_valid(form, formsets)
if formsets_validated and form_validated and cross_validated:
#...
Die neue Funktion is_cross_valid (...) wie folgt definiert ist:
def is_cross_valid(self, form, formsets):
return True
so die neue Klasse sollte genau arbeiten das gleiche wie ModelAdmin, wenn Sie die Funktion is_cross_valid (...) nicht ändern.
Jetzt sieht mein admin.py wie folgt aus:
###admin.py###
class ModelAdminWithInline(admin.ModelAdmin):
def is_cross_valid(self, form, formsets):
return True
def add_view(self, request, form_url='', extra_context=None):
#modified code
def change_view(self, request, object_id, extra_context=None):
#modified code
class ModelChildInline(admin.TabularInline):
model = ModelChild
class ModelParentAdmin(ModelAdminWithInline):
inlines = [ModelChildInline]
def is_cross_valid(self, form, formsets):
#Do some cross validation on forms
#For example, here is my particular validation:
valid = True
if hasattr(form, 'cleaned_data'):
subjects_parent = form.cleaned_data.get("subjects_parent")
#You can access forms from formsets like this:
for formset in formsets:
for formset_form in formset.forms:
if hasattr(formset_form, 'cleaned_data'):
subjects_child = formset_form.cleaned_data.get("subjects_child")
delete_form = formset_form.cleaned_data.get("DELETE")
if subjects_child and (delete_form == False):
for subject in subjects_child:
if subject in subjects_parent:
valid = False
#From here you can still report errors like in regular forms:
if "subjects_child" in formset_form.cleaned_data.keys():
formset_form._errors["subjects_child"] = ErrorList([u"Subject %s is already selected in parent ModelParent" % subject])
del formset_form.cleaned_data["subjects_child"]
else:
formset_form._errors["subjects_child"] += ErrorList(u"Subject %s is already selected in parent ModelParent" % subject])
#return True on success or False otherwise.
return valid
admin.site.register(ModelParent, ModelParentAdmin)
Die Lösung ein wenig hackish ist, aber es funktioniert :). Die Fehler entsprechen den regulären Klassen ModelForm und ModelAdmin. Django 1.2 (welches in Kürze veröffentlicht werden sollte) sollte eine Modellvalidierung haben, also hoffe ich, dass dieses Problem dann besser gelöst werden kann.
Warum validieren Sie es in der clean() für das Formular, nicht die field_specific sauber? Auf diese Weise werden alle Felder, die Sie überprüfen müssen, vorgereinigt. Die einzige Sache, die ich nicht sicher bin, ist, ob Sie beide Sätze von Daten oder nur die Daten für das ModelParent in der sauberen() ... –
Thx für Vorschlag erreichen können. Ich habe das schon gemacht, aber mit Formularen kann ich nur das Hauptformular (Formular für ModelParentAdmin) und das Iniline-Formset separat validieren (nur gegen die db). Der einzige Ort, an dem ich auf sie zugreifen kann, ist die ModelParentAdmin-Klasse. Aber diese Klasse hat keine clean() -Methode. Ich kann mir vorstellen, sie zu validieren, bevor sie in der Methode save_formsets (...) dieser Klasse verwendet werden, aber wenn ValidationError ("error") ausgelöst wird, fängt es nichts ein. – blazt