2009-08-07 6 views

Répondre

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 = ('field',) – falko

+0

Que faire si le champ est un champ personnalisé dans le formulaire d'administration? –

+1

Voir les réponses ci-dessous pour savoir pourquoi c'est dangereux et pas la voie à suivre. Les objets Admin étant des singletons, la définition de self.exclude modifie l'état de SubSectionAdmin pour les appels add_view suivants. – aggieNick02

10

La réponse de orwellien fera toute SubSectionAdmin singleton changer sa propriété exclure.

Une façon de faire en sorte que les champs sont exclus sur une base par demande est de faire quelque chose comme:

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) 

qui vient informer le formulaire d'exclure ces champs supplémentaires.

Je ne sais pas comment cela se comportera donné un champ obligatoire étant exclu ...

+9

Il devrait y avoir 'kwargs.update' à la place de' kwargs.extend'. – Mitar

0

L'approche ci-dessous présente l'avantage de ne pas l'objet primordial large exclude propriété; En revanche, il est remis à zéro en fonction de chaque type de demande

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

Les classes ModelAdmin sont des singletons, donc la modification de leur état est problématique – aggieNick02

4

Réglage self.exclude fait comme @ steve-brochet mentionne, faire changer sa propriété exclure toute SubSectionAdmin singleton. Un singleton est une classe qui réutilisera la même instance chaque fois que la classe est instanciée. Une instance est donc créée à la première utilisation du constructeur et l'utilisation suivante du constructeur renvoie la même instance. Voir le wiki page pour une description plus inepte. Cela signifie que si vous écrivez du code pour exclure le champ lors d'un changement, cela impliquera que si vous ajoutez un élément pour la première fois, le champ sera présent, mais si vous ouvrez un élément pour le modifier, le champ sera exclu. visites à la page d'ajout.

La façon la plus simple d'obtenir un comportement par la demande, est d'utiliser get_fields et test sur l'argument obj, qui est None si nous ajoutons un objet, et une instance d'un objet si nous changeons un objet. La méthode get_fields est disponible auprès de Django 1.7.

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 

Mise à jour:

S'il vous plaît noter que get_fields peut retourner un tuple, vous devrez peut-être convertir fields dans une liste pour supprimer des éléments. Vous pouvez également rencontrer une erreur si le nom du champ que vous essayez de supprimer ne figure pas dans la liste. Par conséquent, il peut, dans certains cas où vous avez d'autres facteurs qui excluent les champs, mieux de construire un ensemble de exclut et de supprimer l'aide d'une compréhension de la liste:

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] 

Sinon, vous pouvez aussi faire un deepcopy du résultat dans la get_fieldsets méthode qui, dans d'autres cas d'utilisation, peut vous donner accès à un meilleur contexte pour exclure des éléments. Le plus évidemment, cela sera utile si vous avez besoin d'agir sur le nom du jeu de champs.En outre, c'est la seule façon d'aller si vous utilisez réellement les ensembles de champs puisque cela omet l'appel à get_fields.

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 
Questions connexes