Переопределение массового удаления моделей в Django - PullRequest
0 голосов
/ 23 апреля 2020

Я написал собственный метод delete для модели. Похоже, что он работает с двумя оговорками.

  1. Когда я вхожу в экземпляр модели внутри Django Admin и нажимаю удалить, тогда файл удаляется из корзины AWS S3 (что была цель переопределения метода в первую очередь). Сама модель также удаляется.

  2. Если я удаляю с помощью функции «Удалить выбранное», то файл задерживается на S3, но экземпляр удаляется из списка экземпляров этого type.

Насколько я понимаю, при массовом удалении вызывается другой метод (queryset).

Мой вопрос: какой самый эффективный способ заставить одинаковые и массовые удаления действовать одинаково? Стоит ли пытаться создать собственный менеджер для этой модели?

Объявление модели и метод удаления:

from boto3.session import Session
from django.conf import settings

class Video(models.Model):
    title=models.CharField(max_length=500)
    description=models.TextField(default="")
    creation_date=models.DateTimeField(default=timezone.now)
    videofile=models.FileField(upload_to='videos/', null=True, verbose_name="")
    tags = TaggableManager()

    actions = ['delete']

    def __str__(self):
        return self.title + ": " + str(self.videofile)

    def delete(self, *args, **kwargs):
        session = Session (settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
        s3_resource = session.resource('s3')
        s3_bucket = s3_resource.Bucket(settings.AWS_STORAGE_BUCKET_NAME)

        file_path = "media/" + str(self.videofile)
        response = s3_bucket.delete_objects(
            Delete={
                'Objects': [
                    {
                        'Key': file_path
                    }
                ]
            })
        print(file_path)
        print(response)
        super(Video, self).delete(*args, **kwargs)

1 Ответ

1 голос
/ 23 апреля 2020

Вы выполняете бесполезную работу, так как массовое удаление не использует метод удаления модели ( документы )

Имейте в виду, что это, по возможности, будет выполняться исключительно в SQL, и поэтому методы delete () отдельных экземпляров объекта не обязательно будут вызываться во время процесса. Если вы предоставили пользовательский метод delete () для класса модели и хотите, чтобы он вызывался, вам нужно будет «вручную» удалить экземпляры этой модели (например, путем итерации по QuerySet и вызова delete () для каждый объект в отдельности) вместо использования метода массового удаления () в QuerySet.

Django Администратор удаляет выбранные объекты не вызывает Модели удаляют метод (аналогично любой набор запросов для массового удаления )

Из Django документации действий администратора

Предупреждение

Действие «удалить выбранные объекты» использует QuerySet.delete () из соображений эффективности, что имеет важное предостережение: метод delete () вашей модели вызываться не будет.

Если вы переопределите это поведение sh вы можете переопределить ModelAdmin.delete_queryset() или написать пользовательское действие, которое выполняет удаление по вашему желанию, например, вызвав Model.delete () для каждого из выбранных элементов.

...