Donnerstag, Juni 4, 2020

Entfernen von Feldern aus ModelForm

habe ich eine einfache ModelForm:

class MyForm(ModelForm):

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        del self.fields['name']

Wie Sie sehen, kann ich versuchen, Sie zu entfernen Sie ein Feld aus der Formular-Liste Feld (das Feld endgültig im Modell vorhanden), aber ich bekomme eine Exception:

TemplateSyntaxError at [..]

Caught an exception while rendering: "Key 'name' not found in Form"

Ich nicht schreiben ein benutzerdefiniertes Formular, also die Vorlage, wo der Fehler Auftritt ist:

/templates/admin/includes/fieldset.html, error at line 4

Irgendwelche Ideen?

— UPDATE —

Scheint das problem nur in den admin-Bereich.

— UPDATE 2 —

Vielleicht eine trace-dump gibt mehr info:

Original Traceback (most recent call last):
  File "/Library/Python/2.5/site-packages/django/template/debug.py", line 71, in render_node
    result = node.render(context)
  File "/Library/Python/2.5/site-packages/django/template/defaulttags.py", line 155, in render
    nodelist.append(node.render(context))
  File "/Library/Python/2.5/site-packages/django/template/defaulttags.py", line 239, in render
    value = bool_expr.resolve(context, True)
  File "/Library/Python/2.5/site-packages/django/template/__init__.py", line 546, in resolve
    obj = self.var.resolve(context)
  File "/Library/Python/2.5/site-packages/django/template/__init__.py", line 687, in resolve
    value = self._resolve_lookup(context)
  File "/Library/Python/2.5/site-packages/django/template/__init__.py", line 722, in _resolve_lookup
    current = current()
  File "/Library/Python/2.5/site-packages/django/contrib/admin/helpers.py", line 81, in errors
    return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]).strip('\n'))
  File "/Library/Python/2.5/site-packages/django/forms/forms.py", line 105, in __getitem__
    raise KeyError('Key %r not found in Form' % name)
KeyError: "Key 'name' not found in Form"

In den admin-Bereich, ich benutze die Grapelli-Thema. Vielleicht hat das mit dem problem zu tun?

  • Magisch™ funktioniert es jetzt, obwohl ich nicht weiß, warum. Trotzdem danke für deine Hilfe.
InformationsquelleAutor schneck | 2009-09-23

5 Kommentare

  1. 13

    Ich hatte das gleiche problem. Dies ist, wie ich es in der neuen Django (Rumpf):

    class MyModelAdmin(admin.ModelAdmin):
        # Your stuff here..
    
        def get_form(self, request, obj=None, **kwargs):
            if request.user.is_staff: # condition
                self.exclude = ('field',)
            return super(PublishAdmin, self).get_form(request, obj=obj, **kwargs)

    Durch überschreiben der get_form – Methode und setzen die Logik hier können Sie auswählen, welche Form Sie dargestellt haben möchten. Habe ich oben angezeigt die standard-form, wenn eine Bedingung erfüllt wird.

    • Wow, natürlich, das macht Sinn. Dies ist, wie ich es angepasst für meinen Gebrauch: a) initialisieren MyModelAdmin mit exclude = [] (oder was auch immer die Basis ausgenommen sind) und dann self.exclude.append('field') wenn die Bedingungen erfüllt sind.
    • Auch nur ein Hinweis (das konnte ich nicht Bearbeiten, weil es zu klein war): user.is_staff ist eine Eigenschaft, keine Methode, so ruft es wirft einen Fehler.
    • Ist das thread-safe?
    • Sollte es nicht obj=obj als zweites argument an die super-Methode der Klasse aufrufen?
  2. 6

    Wie beschrieben in Erstellen von Formen von Modellen – die Auswahl der Felder verwenden, gibt es drei Möglichkeiten:

    1. In das Modell, set editable=False. Alle Formulare erstellt, aus dem Modell ausgeschlossen werden, das Feld.
    2. Definieren die fields Attribut in der Meta innere Klasse, um nur die Felder, die Sie wollen.
    3. Definieren die exclude Attribut in der Meta innere Klasse, um eine Liste der Felder, die Sie nicht wollen.

    Also, wenn Ihr Modell hat die Felder field1, field2, und field3 und Sie nicht möchten, dass field3 Technik #2 würde dann wie folgt Aussehen:

    class MyModelForm(ModelForm):
        class Meta:
            model = MyModel
            fields = ('field1', 'field2')

    Technik und #3 würde so Aussehen:

    class MyModelForm(ModelForm):
        class Meta:
            model = MyModel
            exclude = ('field3',)
    • Wie ich schon schrieb in meinem Kommentar oben, ich habe zum entfernen von Feldern dynamisch, bedeutet, in der init-Methode. Daher ist es nicht möglich, die Methoden verwenden, die Sie vorgeschlagen.
    • Was meinst du mit entfernen der Felder „dynamisch“?
    • das bedeutet, dass die Felder angezeigt werden (/validiert/gespeichert) werden zur Laufzeit bestimmt, nicht zur design-Zeit
    • Okay, was sind Sie eigentlich versuchen zu tun, dass Sie brauchen, um zu ändern, welche Felder angezeigt werden, die zur Laufzeit?
    • In meinem Projekt gibt es ein Modell, mit vielen Feldern, und für die user, ist es möglich, die Auswahl einer Teilmenge von Feldern, die er braucht. Das funktioniert bereits einwandfrei außer das nervige problem im admin-backend.
    • editable=false sollte editable=False 😉

  3. 3

    Dieser funktioniert Super…

    def __init__(self, instance, *args, **kwargs):    
        super(FormClass, self).__init__(instance=instance, *args, **kwargs)
        if instance and instance.item:
            del self.fields['field_for_item']
    • AFAIK field_for_item wird auf none gesetzt, wenn es fehlt, ist in form.cleaned_data. Vorsicht: dies könnte löschen Sie die Werte in die db-Spalte field_for_item!
  4. 1

    Einer Ursache, die ich denken kann, ist, wenn Ihr ModelAdmin welche Klasse verwendet Ihr benutzerdefiniertes Formular widersprüchliche Einstellungen. Zum Beispiel, wenn Sie auch explizit angegebenen Feld „name“ in „Felder“ oder „fieldsets“ von Ihrem ModelAdmin.

    • Nein, ich hatte einen tieferen Blick in den code, gibt es keine harten Hinweise, wie diese.
  5. 0

    Können Sie die exclude-Eigenschaft zu entfernen Felder aus einer ModelForm

    exclude = ('field_name1', 'field_name2,)
    • Ich weiß, aber ich habe zum entfernen von Feldern dynamisch.

Kostenlose Online-Tests