2009-10-14 7 views

Répondre

12

Je ne sais pas si ce genre de singe-patcher est une bonne idée, mais bousculant ce dans un de mes admin.py œuvres pour moi:

from django.contrib.admin.actions import delete_selected 
delete_selected.short_description = u'How\'s this for a name?' 

Cela va changer le nom verbeux pour tous vos sites admin . Si vous voulez le changer juste pour l'admin d'un modèle particulier, je pense que vous devrez écrire un custom admin action.

testé avec la version Django 1.1:

>>> import django 
>>> django.VERSION 
(1, 1, 0, 'beta', 1) 
+0

semble une façon intelligente pour moi, ce ne travail. Il supprime simplement la boîte d'action. – Hellnar

+1

Huh. Je l'ai testé avec Django 1.1 et ça marche bien. Je l'ai mis en haut (en dessous des autres instructions d'importation) de mon admin.py. –

+0

c'est (1, 1, 0, 'final', 0) pour moi, c'est peut-être la raison :( – Hellnar

19

Vous pouvez désactiver l'action d'apparaître avec ce code.

from django.contrib import admin 
admin.site.disable_action('delete_selected') 

Si vous avez choisi, vous pouvez ensuite restaurer sur les modèles individuels avec ceci:

class FooAdmin(admin.ModelAdmin): 
    actions = ['my_action', 'my_other_action', admin.actions.delete_selected] 
+0

c'est fantastique - fonctionne très bien. – Mark

+0

Utiliser également 'delete_selected' au lieu de admin.actions.delete_selected fonctionne très bien dans Django 1.6. –

4

Pour remplacer delete_selected je fais ce qui suit:

Copie la fonction delete_selected de contrib/admin/actions.py à votre admin.py et renommez-le. Copiez également le modèle contrib/admin/templates/delete_selected_confirmation.html dans votre répertoire de modèles et renommez-le. Le mien ressemble à ceci:

def reservation_bulk_delete(modeladmin, request, queryset): 
    """ 
    Default action which deletes the selected objects. 
    This action first displays a confirmation page whichs shows all the 
    deleteable objects, or, if the user has no permission one of the related 
    childs (foreignkeys), a "permission denied" message. 

    Next, it delets all selected objects and redirects back to the change list. 
    """ 
    opts = modeladmin.model._meta 
    app_label = opts.app_label 

    # Check that the user has delete permission for the actual model 
    if not modeladmin.has_delete_permission(request): 
     raise PermissionDenied 

    # Populate deletable_objects, a data structure of all related objects that 
    # will also be deleted. 

    # deletable_objects must be a list if we want to use '|unordered_list' in the template 
    deletable_objects = [] 
    perms_needed = set() 
    i = 0 
    for obj in queryset: 
     deletable_objects.append([mark_safe(u'%s: <a href="%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), obj.pk, escape(obj))), []]) 
     get_deleted_objects(deletable_objects[i], perms_needed, request.user, obj, opts, 1, modeladmin.admin_site, levels_to_root=2) 
     i=i+1 

    # The user has already confirmed the deletion. 
    # Do the deletion and return a None to display the change list view again. 
    if request.POST.get('post'): 
     if perms_needed: 
      raise PermissionDenied 
     n = queryset.count() 
     if n: 
      for obj in queryset: 
       obj_display = force_unicode(obj) 

       obj.delete() 

       modeladmin.log_deletion(request, obj, obj_display) 
      #queryset.delete() 
      modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { 
       "count": n, "items": model_ngettext(modeladmin.opts, n) 
      }) 
     # Return None to display the change list page again. 
     return None 

    context = { 
     "title": _("Are you sure?"), 
     "object_name": force_unicode(opts.verbose_name), 
     "deletable_objects": deletable_objects, 
     'queryset': queryset, 
     "perms_lacking": perms_needed, 
     "opts": opts, 
     "root_path": modeladmin.admin_site.root_path, 
     "app_label": app_label, 
     'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 
    } 

    # Display the confirmation page 
    return render_to_response(modeladmin.delete_confirmation_template or [ 
     "admin/%s/%s/reservation_bulk_delete_confirmation.html" % (app_label, opts.object_name.lower()), 
     "admin/%s/reservation_bulk_delete_confirmation.html" % app_label, 
     "admin/reservation_bulk_delete_confirmation.html" 
    ], context, context_instance=template.RequestContext(request)) 

Comme vous pouvez le voir j'ai commenté

queryset.delete() 

et utiliser plutôt:

obj.delete() 

Ce n'est pas optimale encore - vous devez appliquer quelque chose à l'ensemble queryset pour de meilleures performances.

En admin.py désactiver l'action par défaut delete_selected pour l'ensemble du site admin:

admin.site.disable_action('delete_selected') 

Au lieu de cela j'utiliser ma propre fonction en cas de besoin:

class ReservationAdmin(admin.ModelAdmin): 
    actions = [reservation_bulk_delete, ] 

Dans mon modèle, je définir la delete() fonction:

class Reservation(models.Model): 
    def delete(self): 
     self.status_server = RESERVATION_STATUS_DELETED 
     self.save() 
23

Alternativement à la solution de Googol, et en attendant delete_model() à be implemented in current Django version, je suggère le code suivant.

Il désactive l'action de suppression par défaut pour l'AdminForm actuel uniquement.

class FlowAdmin(admin.ModelAdmin): 
    actions = ['delete_model'] 

    def get_actions(self, request): 
     actions = super(MyModelAdmin, self).get_actions(request) 
     del actions['delete_selected'] 
     return actions 

    def delete_model(self, request, obj): 
     for o in obj.all(): 
      o.delete() 
    delete_model.short_description = 'Delete flow' 

admin.site.register(Flow, FlowAdmin) 
+1

'delete_model' ne devrait pas être utilisé, puisque cette méthode est utilisée lors de la suppression d'une instance de l'admin. Dans ce cas, l'argument queryset n'est pas un ensemble de requêtes, c'est une instance unique, et cela fait planter la boucle. – jul

+0

Celui-ci doit être sélectionné comme répondeur accepté. –

+0

J'utilise django 1.4.16 et 'delete_model' semble fonctionner dans les deux cas (pas d'exceptions ou de boucles). – Paolo

3

Pour changer le monde entier short_description de delete_selected Dominic Rodger « s answer semble mieux.

Cependant pour changer la SHORT_DESCRIPTION l'administrateur pour un seul modèle, je pense que cette alternative à l » answerStéphane est mieux:

def get_actions(self, request): 
    actions = super(MyModelAdmin, self).get_actions(request) 
    actions['delete_selected'][0].short_description = "Delete Selected" 
    return actions 
0
from django.contrib.admin import sites 
from django.contrib.admin.actions import delete_selected 


class AdminSite(sites.AdminSite): 
    """ 
    Represents the administration, where only authorized users have access. 
    """ 
    def __init__(self, *args, **kwargs): 
     super(AdminSite, self).__init__(*args, **kwargs) 
     self.disable_action('delete_selected') 
     self.add_action(self._delete_selected, 'delete_selected') 

    @staticmethod 
    def _delete_selected(modeladmin, request, queryset): 
     _delete_qs = queryset.delete 

     def delete(): 
      for obj in queryset: 
       modeladmin.delete_model(request, obj) 
      _delete_qs() 

     queryset.delete = delete 
     return delete_selected(modeladmin, request, queryset) 
0
class FooAdmin(sites.AdminSite): 
     not_deleted = ['value1', 'value2'] 
     actions = ['delete_selected_values'] 

    def delete_selected_values(self, request, queryset): 
     # my custom logic 
     exist = queryset.filter(value__in=self.not_deleted).exists() 
     if exist: 
      error_message = "Error" 
      self.message_user(request, error_message, level=messages.ERROR) 
     else: 
      delete_action = super().get_action('delete_selected')[0] 
      return delete_action(self, request, queryset) 
    delete_selected_values.short_description = 'delete selected' 

admin.site.register(Foo, FooAdmin) 
+1

Bienvenue dans StackOverflow! S'il vous plaît, commentez votre code – tutankhamun

Questions connexes