Saltar al contenido

Administrador de Django: anular el método de eliminación

Sé libre de divulgar nuestro espacio y códigos en tus redes, danos de tu ayuda para ampliar esta comunidad.

Solución:

Estás en el camino correcto con tu delete_model método. Cuando el administrador de django realiza una acción en varios objetos a la vez, usa la función de actualización. Sin embargo, como puede ver en los documentos, estas acciones se realizan a nivel de base de datos solo usando SQL.

Necesitas agregar tu delete_model como una acción personalizada en django admin.

def delete_model(modeladmin, request, queryset):
    for obj in queryset:
        filename=obj.profile_name+".xml"
        os.remove(os.path.join(obj.type,filename))
        obj.delete()

Luego agregue su función a su modeladmin –

class profilesAdmin(admin.ModelAdmin):
    list_display = ["type","username","domain_name"]
    actions = [delete_model]

Puede usar el delete_queryset que viene de Django 2.1 en adelante para eliminar objetos de forma masiva y el delete_model para un solo borrado. Ambos métodos manejarán algo antes de eliminar el objeto.

ModelAdmin.delete_queryset (solicitud, conjunto de consultas)


Esta es la explicación sobre delete_queryset en la nota de lanzamiento de Django 2.1.

El método delete_queryset () recibe la HttpRequest y un QuerySet de objetos que se eliminarán. Anule este método para personalizar el proceso de eliminación de “eliminar objetos seleccionados”

Veamos qué hace delete_queryset, puede anular la clase admin.ModelAdmin de esta manera al incluir la función delete_queryset. Aquí obtendrá una lista de objetos, queryset.delete() significa eliminar todos los objetos a la vez o puede agregar un bucle para eliminar uno por uno.

def delete_queryset(self, request, queryset):
    print('==========================delete_queryset==========================')
    print(queryset)

    """
    you can do anything here BEFORE deleting the object(s)
    """

    queryset.delete()

    """
    you can do anything here AFTER deleting the object(s)
    """

    print('==========================delete_queryset==========================')

Así que voy a eliminar 5 objetos de la “ventana de selección” y aquí están esos 5 objetos.

eliminando 5 objetos de

Luego, lo redireccionará a la página de confirmación como esta,

voy a borrar esos 5 objetos

Tenga en cuenta el botón “Sí, estoy seguro” y lo explicaré más tarde. Cuando haga clic en ese botón, verá la imagen de abajo después de eliminar esos 5 objetos.

eliminado con éxito 5 objetos

Esta es la salida del terminal,

salida terminal de esos 5 objetos

Entonces obtendrá esos 5 objetos como una lista de QuerySet y, antes de eliminar, puede hacer lo que quiera en el área de comentarios.

ModelAdmin.delete_model (solicitud, obj)


Esta es la explicación sobre delete_model.

El método delete_model recibe HttpRequest y una instancia de modelo. Anular este método permite realizar operaciones previas o posteriores a la eliminación. Llame a super (). Delete_model () para eliminar el objeto usando Model.delete ().

Veamos qué hace delete_model, puede anular la clase admin.ModelAdmin de esta manera al incluir la función delete_model.

actions = ['delete_model']

def delete_model(self, request, obj):
    print('============================delete_model============================')
    print(obj)

    """
    you can do anything here BEFORE deleting the object
    """

    obj.delete()

    """
    you can do anything here AFTER deleting the object
    """

    print('============================delete_model============================')

Simplemente hago clic en mi sexto objeto para eliminarlo de la “ventana de cambio”.

eliminando 1 objeto de

Hay otro botón Eliminar, al hacer clic en él, verá la ventana que vimos anteriormente.

voy a borrar esos 1 objeto

Haga clic en el botón “Sí, estoy seguro” para eliminar el único objeto. Verá la siguiente ventana con la notificación de ese objeto eliminado.

eliminado correctamente 1 objeto

Esta es la salida del terminal,

salida terminal de esos 1 objeto

Por lo tanto, obtendrá el objeto seleccionado como único de QuerySet y, antes de eliminarlo, puede hacer lo que quiera en el área de comentarios.


los conclusión final es que puede manejar el evento de eliminación haciendo clic en el botón “Sí, estoy seguro” en “ventana de selección” o “ventana de cambio” en el sitio de administración de Django usando delete_queryset y delete_model. De esta manera, no necesitamos manejar señales como django.db.models.signals.pre_delete o django.db.models.signals.post_delete.

Aquí está el código completo,

from django.contrib import admin

from . import models

class AdminInfo(admin.ModelAdmin):
    model = models.AdminInfo
    actions = ['delete_model']

    def delete_queryset(self, request, queryset):
        print('========================delete_queryset========================')
        print(queryset)

        """
        you can do anything here BEFORE deleting the object(s)
        """

        queryset.delete()

        """
        you can do anything here AFTER deleting the object(s)
        """

        print('========================delete_queryset========================')

    def delete_model(self, request, obj):
        print('==========================delete_model==========================')
        print(obj)

        """
        you can do anything here BEFORE deleting the object
        """

        obj.delete()

        """
        you can do anything here AFTER deleting the object
        """

        print('==========================delete_model==========================')

admin.site.register(models.AdminInfo, AdminInfo)

El problema principal es que la eliminación masiva del administrador de Django usa SQL, no instance.delete (), como se señaló en otra parte. Para una solución solo para administradores, la siguiente solución conserva el intersticial “¿realmente quieres eliminar estos?” Del administrador de Django.

La solución más general es anular el conjunto de consultas devuelto por el administrador del modelo para interceptar la eliminación.

from django.contrib.admin.actions import delete_selected

class BulkDeleteMixin(object):
    class SafeDeleteQuerysetWrapper(object):
        def __init__(self, wrapped_queryset):
            self.wrapped_queryset = wrapped_queryset

        def _safe_delete(self):
            for obj in self.wrapped_queryset:
                obj.delete()

        def __getattr__(self, attr):
            if attr == 'delete':
                return self._safe_delete
            else:
                return getattr(self.wrapped_queryset, attr)

        def __iter__(self):
            for obj in self.wrapped_queryset:
                yield obj

        def __getitem__(self, index):
            return self.wrapped_queryset[index]

        def __len__(self):
            return len(self.wrapped_queryset)

    def get_actions(self, request):
        actions = super(BulkDeleteMixin, self).get_actions(request)
        actions['delete_selected'] = (BulkDeleteMixin.action_safe_bulk_delete, 'delete_selected', ugettext_lazy("Delete selected %(verbose_name_plural)s"))
        return actions

    def action_safe_bulk_delete(self, request, queryset):
        wrapped_queryset = BulkDeleteMixin.SafeDeleteQuerysetWrapper(queryset)
        return delete_selected(self, request, wrapped_queryset)

class SomeAdmin(BulkDeleteMixin, admin.ModelAdmin):
    ...

Si te ha sido útil este post, te agradeceríamos que lo compartas con más juniors y nos ayudes a difundir esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *