Подтвердить что ты не робот

По умолчанию действие "удалить выбранное" admin в Django

Как удалить или изменить подробное имя действия администратора по умолчанию "удалить выбранный элемент X" в панели администратора Django?

4b9b3361

Ответ 1

Не уверен, что эта маска для обезьян - хорошая идея, но для меня это работает в одном из моих admin.py:

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

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

Протестировано с версией Django 1.1:

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

Ответ 2

В качестве альтернативы решению Googol и ожидая, что delete_model() в будет реализован в текущей версии Django, я предлагаю следующий код.

Отключает действие удаления по умолчанию только для текущего AdminForm.

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)

Ответ 3

Вы можете отключить действие от появления этого кода.

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

Если вы выбрали, вы можете восстановить его на отдельных моделях с помощью этого:

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

Ответ 4

Чтобы заменить delete_selected, я делаю следующее:

Скопируйте функцию delete_selected из contrib/admin/actions.py в admin.py и переименуйте ее. Также скопируйте шаблон contrib/admin/templates/delete_selected_confirmation.html в каталог вашего шаблона и переименуйте его. Мой выглядит так:

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

Как вы можете видеть, я прокомментировал

queryset.delete()

и скорее используйте:

obj.delete()

Это еще не оптимально - вы должны применить что-то ко всему набору запросов для повышения производительности.

В admin.py отключить действие по умолчанию delete_selected для всего сайта администратора:

admin.site.disable_action('delete_selected')

Вместо этого я использую свою собственную функцию, если необходимо:

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

В моей модели я определяю функцию delete():

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

Ответ 6

Для глобального изменения delete_selected short_description Dominic Rodger ответ кажется лучшим.

Однако для изменения short_description в admin для одной модели я думаю, что эта альтернатива Стефан ответ лучше:

def get_actions(self, request):
    actions = super(MyModelAdmin, self).get_actions(request)
    actions['delete_selected'][0].short_description = "Delete Selected"
    return actions

Ответ 7

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)

Ответ 8

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)