Александр Кошелев
Александр Кошелев Python-разработчик

Revisited: Чуть более быстрое удаление объектов в админке

Итак, продолжаю переосмысливать прошлые свои советы и снипеты, которые в нынешних условиях можно реализовать более правильно и изящно.

Сейчас вот посмотрим на проблему добавления к list-view в админке своей “кнопки” с каким-то действием. Возвращаясь к старому посту про “быстрое удаление”, можно придумать несколько вариантов реализации подобной концепции, но уже со свежей джангой. Вот они:

  • Для Django 1.0. Поскольку в 1.0 старая админка канула в лету, то reverse('django.contrib.admin.views.main.delete_stage') уже не работает. Но не страшно, код метода модели достаточно чуть-чуть изменить:

     def remove(self):
        from django.core.urlresolvers import reverse
        from django.contrib import admin
        return '<a href="%s" class="deletelink">Delete</a>'\
                    % reverse(admin.site.root,
                               args=("/".join([self.__class__._meta.app_label,
                                        self.__class__._meta.object_name,
                                        self.pk, 'delete']),)))
    

Это конечно при условии, что вы используете дефолтный админский сайт (объект admin.site), иначе root надо указать объекта используемого кастомного сайта.

Но лучше поступить по другому. Перенести этот метод в ModelAdmin класс, описывающий админку для данной модели, изменив его например так:

    class EntryAdmin(admin.ModelAdmin):
       #...
       list_display = [..., 'remove_link', ...]
       #...
            
       def remove_link(self, entry):
          from django.core.urlresolvers import reverse
          return '<a href="%s" class="deletelink">Delete</a>'\
                       % reverse(self.admin_site.root,
                                  args=("/".join([self.model._meta.app_label,
                                             self.model._meta.object_name,
                                             entry.pk, 'delete']),))

При таком подходе мы получаем более переносимое решение, поскольку мы уже не зависим от какой-го конкретного админского сайта, а используем именно тот в котором зарегистрирован этот класс ModelAdmin.

  • Для Django 1.1 (и уже для текущего trunk).. Имея текущий код Джанги, и учитывая изменения, которые были внесены в логику диспетчерезации админских урлов, код можно адаптировать иначе:

      def remove_link(self, entry):
         from django.core.urlresolvers import reverse
         name = '%sadmin_%s_%s_delete' % (
              self.admin_site.name,
              self.model._meta.app_label,
              self.model._meta.module_name
         )
         return '<a href="%s" class="deletelink">Delete</a>'\
                      % reverse(name, args=(entry.pk,))
    

В актуальной Джанге теперь админские урлы гораздо проще реверсятся, так то это можно считать рекомендуемым способом.

Но тут версия 1.1 преподносит нам ещё одну возможность упростить работу с админкой - это групповые операции над объектами. Потрясающе удобная штука в повседневной работе, тем более что групповое удаление объектов доступно “из коробки”. Хоть нашу задачу и решает косвенно, применимо к одному объекту, но вот зато когда их несколько… Я например этой штукой убиваю комментарии со спамом, которые Акисмет мне помечает - мега удобно.

Не расслабляемся и держим руку на пульсе!:-)

comments powered by Disqus