2009-10-14 12 views

Respuesta

12

No estoy seguro si este tipo de mono-aplicación de parches es una buena idea, pero empujando esto en uno de mis admin.py funciona para mí:

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

Esto cambiará el nombre descriptivo para todo sus sitios de administración . Si desea cambiarlo solo para el administrador de un modelo en particular, creo que tendrá que escribir un custom admin action.

probado con la versión 1.1 de Django:

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

parece una forma inteligente para mí no lo hace trabajo. Simplemente elimina el cuadro de acción. – Hellnar

+1

Huh. Lo probé con Django 1.1 y funciona bien. Lo coloco justo en la parte superior (debajo de las otras declaraciones de importación) de mi admin.py. –

+0

es (1, 1, 0, 'final', 0) para mí, tal vez esa sea la razón :( – Hellnar

19

puede desactivar la acción de aparecer con este código.

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

Si ha elegido, entonces podría restaurarla en modelos individuales con esto:

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

esto es fantástico, funciona genial. – Mark

+0

También usar 'delete_selected' en lugar de admin.actions.delete_selected funciona bien en Django 1.6. –

4

el fin de reemplazar delete_selected hago lo siguiente:

copiar la función delete_selected de contrib/admin/actions.py a su admin.py y cambie el nombre. Copie también la plantilla contrib/admin/templates/delete_selected_confirmation.html en su directorio de plantillas y cámbiele el nombre. El mío se parece a esto:

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)) 

Como se puede ver que comentada

queryset.delete() 

y en lugar de usar:

obj.delete() 

Eso todavía no lo es óptima - usted debe aplicar algo para todo el conjunto de consultas para un mejor rendimiento.

En admin.py desactivo la acción predeterminada delete_selected para todo el sitio de administración:

admin.site.disable_action('delete_selected') 

En lugar de eso utiliza mi propia función cuando sea necesario:

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

En mi modelo que definen el delete() función:

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

Alternativamente a la solución de Googol, y esperando delete_model() a be implemented in current Django version, sugiero el siguiente código.

Deshabilita la acción de eliminación predeterminada para el formulario de administración actual solamente.

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' no se debe utilizar, ya que este método se usa al eliminar una instancia del administrador. En ese caso, el argumento queryset no es un queryset, es una sola instancia y hace que el bucle se cuelgue. – jul

+0

Éste debe ser seleccionado como el contestador aceptado. –

+0

Estoy usando django 1.4.16 y 'delete_model' parece funcionar en ambos casos (sin excepciones ni bucles). – Paolo

3

Para short_description a nivel mundial está cambiando delete_selected Dominic Rodger 's answer parece mejor.

Sin embargo, para cambiar el short_description en el administrador de un solo modelo, creo que este alternativa a Stéphane 's answer es mejor:

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

¡Bienvenido a StackOverflow! Por favor, comenta tu código – tutankhamun

Cuestiones relacionadas