2009-08-07 8 views
4

Gibt es eine Möglichkeit festzustellen, ob Informationen in einem Modell hinzugefügt oder geändert werden.Django-Administrator: Feld nur bei Änderungsformular ausschließen

Wenn dies der Fall ist, können diese Informationen verwendet werden, um Felder auszuschließen.

Einige Pseudocode zu illustrieren, worüber ich spreche.

class SubSectionAdmin(admin.ModelAdmin): 
    if something.change_or_add = 'change': 
     exclude = ('field',) 
    ... 

Dank

Antwort

5
class SubSectionAdmin(admin.ModelAdmin): 
    # ... 
    def change_view(self, request, object_id, extra_context=None):  
     self.exclude = ('field',) 
     return super(SubSectionAdmin, self).change_view(request, object_id, extra_context) 
+0

self.exclude = ('Feld',) – falko

+0

Was ist, wenn das Feld ein benutzerdefiniertes Feld im Admin-Formular ist? –

+1

Siehe die Antworten unten, warum dies gefährlich ist und nicht der richtige Weg. Die Admin-Objekte sind Singletons. Das Setzen von self.exclude ändert den Status von SubSectionAdmin für nachfolgende add_view-Aufrufe. – aggieNick02

10

Antwort des orwellian wird die ganze SubSectionAdmin Singletons seine machen Eigenschaft ausschließen ändern.

Ein Weg, um sicherzustellen, dass die Felder auf einer Pro-Anfrage und ausgeschlossen ist, wie etwas zu tun ist:

class SubSectionAdmin(admin.ModelAdmin): 
    # ... 
    def get_form(self, request, obj=None, **kwargs): 
     """Override the get_form and extend the 'exclude' keyword arg""" 
     if obj: 
      kwargs.update({ 
       'exclude': getattr(kwargs, 'exclude', tuple()) + ('field',), 
      }) 
     return super(SubSectionAdmin, self).get_form(request, obj, **kwargs) 

, die nur das Formular informieren, diese zusätzlichen Felder auszuschließen.

nicht sicher, wie dies ein Pflichtfeld ausgeschlossen gegeben verhalten ...

+9

Es sollte 'kwars.update' anstelle von' kwargs.extend' sein. – Mitar

0

Der Ansatz unten hat den Vorteil, nicht das Überschreiben das Objekt breit exclude Eigenschaft; stattdessen wird es zurückgesetzt basierend auf jede Art von Anfrage

class SubSectionAdmin(admin.ModelAdmin): 
    add_exclude = ('field1', 'field2') 
    edit_exclude = ('field2',) 

    def add_view(self, *args, **kwargs): 
     self.exclude = getattr(self, 'add_exclude',()) 
     return super(SubSectionAdmin, self).add_view(*args, **kwargs) 

    def change_view(self, *args, **kwargs): 
     self.exclude = getattr(self, 'edit_exclude',()) 
     return super(SubSectionAdmin, self).change_view(*args, **kwargs) 
+0

ModelAdmin-Klassen sind Singletons, daher ist das Ändern ihres Status problematisch – aggieNick02

4

Einstellung self.exclude tut als @ steve-Hecht erwähnt, machen die ganze SubSectionAdmin Singleton seine ausschließen Eigenschaft ändern. Ein Singleton ist eine Klasse, die dieselbe Instanz jedes Mal erneut verwendet, wenn die Klasse instanziiert wird. Daher wird eine Instanz nur bei der ersten Verwendung des Konstruktors erstellt, und die nachfolgende Verwendung des Konstruktors gibt dieselbe Instanz zurück. Eine ausführlichere Beschreibung finden Sie unter wiki page. Dies bedeutet, dass wenn Sie Code zum Ausschließen des Felds bei Änderung schreiben, dass wenn Sie zuerst ein Element hinzufügen, das Feld dort sein wird, aber wenn Sie ein Element zur Änderung öffnen, wird das Feld für Ihre folgenden ausgeschlossen Besuche auf der Hinzufügen-Seite.

Der einfachste Weg, eine pro Anfrage Verhalten zu erreichen, ist get_fields und Test auf dem obj Argument zu verwenden, die None ist, wenn wir ein Objekt und eine Instanz eines Objekts, wenn wir ein Objekt ändern sich hinzufügen. Die Methode get_fields ist von Django 1.7 erhältlich.

class SubSectionAdmin(admin.ModelAdmin): 
    def get_fields(self, request, obj=None): 
     fields = super(SubSectionAdmin, self).get_fields(request, obj) 
     if obj: # obj will be None on the add page, and something on change pages 
      fields.remove('field') 
     return fields 

Update:

Bitte beachten Sie, dass get_fields ein Tupel zurückgeben kann, so dass Sie fields in eine Liste umwandeln müssen Elemente zu entfernen. Möglicherweise tritt auch ein Fehler auf, wenn der Feldname, den Sie entfernen möchten, nicht in der Liste enthalten ist. Daher kann es in einigen Fällen, in denen Sie andere Faktoren, die Felder ausschließen, besser sein, einen Satz umfasst nicht zu bauen und entfernen, um eine Liste Verständnis mit:

class SubSectionAdmin(admin.ModelAdmin): 
    def get_fields(self, request, obj=None): 
     fields = list(super(SubSectionAdmin, self).get_fields(request, obj)) 
     exclude_set = set() 
     if obj: # obj will be None on the add page, and something on change pages 
      exclude_set.add('field') 
     return [f for f in fields if f not in exclude_set] 

Alternativ können Sie auch eine deepcopy des Ergebnisses machen in der get_fieldsets Methode, die Ihnen in anderen Anwendungsfällen Zugriff auf einen besseren Kontext zum Ausschließen von Daten geben kann. Am offensichtlichsten ist dies nützlich, wenn Sie auf den Namen des Feldsatzes reagieren müssen.Auch Dies ist die einzige Möglichkeit zu gehen, wenn Sie tatsächlich Feldgruppen verwenden, da dies den Anruf an get_fields weglassen wird.

from copy import deepcopy 

class SubSectionAdmin(admin.ModelAdmin): 
    def get_fieldsets(self, request, obj=None): 
     """Custom override to exclude fields""" 
     fieldsets = deepcopy(super(SubSectionAdmin, self).get_fieldsets(request, obj)) 

     # Append excludes here instead of using self.exclude. 
     # When fieldsets are defined for the user admin, so self.exclude is ignored. 
     exclude =() 

     if not request.user.is_superuser: 
      exclude += ('accepted_error_margin_alert', 'accepted_error_margin_warning') 

     # Iterate fieldsets 
     for fieldset in fieldsets: 
      fieldset_fields = fieldset[1]['fields'] 

      # Remove excluded fields from the fieldset 
      for exclude_field in exclude: 
       if exclude_field in fieldset_fields: 
        fieldset_fields = tuple(field for field in fieldset_fields if field != exclude_field) # Filter 
        fieldset[1]['fields'] = fieldset_fields # Store new tuple 

     return fieldsets 
Verwandte Themen