Die akzeptierte Antwort oben hat in älteren Versionen von Django funktioniert, und so habe ich es gemacht. Dies ist jetzt in späteren Django-Versionen kaputt gegangen (Ich bin im Moment auf 1.6.8, aber selbst das ist jetzt alt).
Der Grund, warum es jetzt kaputt ist, liegt darin, dass alle Felder innerhalb von Feldsets, die Sie von ModelAdmin.get_fieldsets()
zurückgeben, letztendlich als das fields=parameter
an modelform_factory()
übergeben werden, was einen Fehler verursacht, weil die auf Ihrer Liste aufgeführten Felder nicht existieren (und erst existieren werden, wenn Ihr Formular instanziiert und sein __init__
aufgerufen wird).
Um dies zu beheben, müssen wir ModelAdmin.get_form()
überschreiben und eine Liste von Feldern bereitstellen, die keine zusätzlichen Felder enthalten, die später hinzugefügt werden. Das Standardverhalten von get_form
besteht darin, get_fieldsets()
für diese Informationen aufzurufen, und das müssen wir verhindern:
# WÄHLEN SIE EINEN
# neuere Versionen von Django verwenden dies
from django.contrib.admin.utils import flatten_fieldsets
# wenn das obige nicht funktioniert, verwenden Sie dies
from django.contrib.admin.util import flatten_fieldsets
class MyModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
# fügen Sie hier Ihre dynamischen Felder hinzu..
for fieldname in ('foo', 'bar', 'baz',):
self.fields[fieldname] = form.CharField()
class MyAdmin(ModelAdmin):
form = MyModelForm
fieldsets = [
# hier geben Sie die Liste der Feldsets ein, die angezeigt werden sollen.. nur
# einschließlich derjenigen, die nicht dynamisch sind
]
def get_form(self, request, obj=None, **kwargs):
# Durch die Übergabe von 'fields' verhindern wir, dass ModelAdmin.get_form die Felder selbst nachschlägt, indem es self.get_fieldsets() aufruft
# Wenn Sie dies nicht tun, erhalten Sie einen Fehler von modelform_factory, der über nicht vorhandene Felder klagt.
# verwende diese Zeile nur für Django vor 1.9 (aber nach 1.5??)
kwargs['fields'] = flatten_fieldsets(self.declared_fieldsets)
# verwende diese Zeile nur für Django 1.9 und später
kwargs['fields'] = flatten_fieldsets(self.fieldsets)
return super(MyAdmin, self).get_form(request, obj, **kwargs)
def get_fieldsets(self, request, obj=None):
fieldsets = super(MyAdmin, self).get_fieldsets(request, obj)
newfieldsets = list(fieldsets)
fields = ['foo', 'bar', 'baz']
newfieldsets.append(['Dynamische Felder', { 'fields': fields }])
return newfieldsets