tipos - Reemplaza el método de eliminación de modelo de django para eliminación masiva
django tutorial (2)
El método Delete de queryset funciona directamente en la base de datos. No llama a los métodos de Model.delete()
. De los documentos :
Tenga en cuenta que, siempre que sea posible, esto se ejecutará exclusivamente en SQL, por lo que los métodos delete () de las instancias de objetos individuales no se llamarán necesariamente durante el proceso. Si ha proporcionado un método delete () personalizado en una clase de modelo y desea asegurarse de que se llame, deberá eliminar "manualmente" las instancias de ese modelo (por ejemplo, iterando sobre un QuerySet y llamando a delete () en cada objeto individualmente) en lugar de usar el método bulk delete () de un QuerySet.
Si desea anular el comportamiento predeterminado de la interfaz de administración de Django, puede escribir una acción de delete
personalizada:
https://docs.djangoproject.com/en/1.7/ref/contrib/admin/actions/
Otro método es anular la post_delete
(o pre_delete
) en lugar de delete
método:
https://docs.djangoproject.com/en/1.7/ref/signals/#django.db.models.signals.post_delete
Como pre_delete, pero enviado al final del método delete () de un modelo y el método delete () de un conjunto de consulta .
Estoy anulando el método de eliminación del modelo de Django para eliminar los archivos huérfanos en el disco de los campos de imagen, algo como esto:
class Image(models.Model):
img = models.ImageField(upload_to=get_image_path)
...
def delete(self, *args, **kwargs):
self.img.delete()
super(Image, self).delete(*args, **kwargs)
Esto funciona bien cuando elimino objetos individuales del administrador, pero cuando selecciono varios objetos y los elimino, parece que no se llama. He estado buscando en Google por un tiempo, pero no he encontrado las palabras clave correctas para obtener la respuesta, ni la documentación oficial parece hablar sobre este tema.
Lo hace :
El método delete () realiza una eliminación masiva y no llama a ningún método delete () en sus modelos. Sin embargo, emite las señales pre_delete y post_delete para todos los objetos eliminados (incluidas las eliminaciones en cascada).
Para que esto funcione, puede anular el método de eliminación en QuerySet
y luego aplicar QuerySet
como administrador:
class ImageQuerySet(models.QuerySet):
def delete(self, *args, **kwargs):
for obj in self:
obj.img.delete()
super(ImageQuerySet, self).delete(*args, **kwargs)
class Image(models.Model):
objects = ImageQuerySet.as_manager()
img = models.ImageField(upload_to=get_image_path)
...
def delete(self, *args, **kwargs):
self.img.delete()
super(Image, self).delete(*args, **kwargs)