PHP前端开发

重写 django 模型中的删除方法

百变鹏仔 1天前 #Python
文章标签 重写
问题内容

我有一个页面模型,在保存对象期间调用 save 方法中的打印。但是,当对象被删除时,不会触发任何打印,并且似乎永远不会调用删除方法。那么我应该如何覆盖默认的删除方法呢?

class Page(models.Model):    image = models.ImageField()    number = models.PositiveIntegerField(default=0, blank=True, null=True)    chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)    def get_upload_path(self, filename):        work_slug = self.chapter.volume.work.slug        translator_name = slugify(self.chapter.volume.translator)        volume_number = self.chapter.volume.number        chapter_number = self.chapter.number        name, extension = filename.rsplit('.', 1)        return f'media/{work_slug}/{translator_name}/volumes/volume-{volume_number}/chapters/chapter-{chapter_number}/page-{self.number}.{extension}'    def save(self, *args, **kwargs):        if not self.pk:            last_page = self.chapter.page_set.last()            if last_page:                self.number = last_page.number + 1        self.image.name = self.get_upload_path(self.image.name)        self.image.storage = s3        print(f"Saving Page with image: {self.image.name}")        super().save(*args, **kwargs)    def delete(self, *args, **kwargs):        print(f"Deleting Page with image: {self.image.name}")        image_name = self.image.name        try:            s3.delete(image_name)            print(f"Successfully deleted from S3: {image_name}")        except Exception as e:            print(f"Error deleting from S3: {e}")        super().delete(*args, **kwargs)

正确答案


删除一个对象时调用 model 的 delete 方法。如果您尝试删除查询集(例如从 django 管理列表页面删除),您必须覆盖模型的查询集。

class PageQuerySet(models.QuerySet):    def delete(self):        print("deleting queryset")        return super().delete()class PageManager(models.Manager):    def get_queryset(self):        return PageQuerySet(model=self.model, using=self._db, hints=self._hints)class Page(models.Model):    image = models.ImageField()    number = models.PositiveIntegerField(default=0, blank=True, null=True)    chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)    objects = PageManager()    def get_upload_path(self, filename):        work_slug = self.chapter.volume.work.slug        translator_name = slugify(self.chapter.volume.translator)        volume_number = self.chapter.volume.number        chapter_number = self.chapter.number        name, extension = filename.rsplit('.', 1)        return f'media/{work_slug}/{translator_name}/volumes/volume-{volume_number}/chapters/chapter-{chapter_number}/page-{self.number}.{extension}'    def save(self, *args, **kwargs):        if not self.pk:            last_page = self.chapter.page_set.last()            if last_page:                self.number = last_page.number + 1        self.image.name = self.get_upload_path(self.image.name)        self.image.storage = s3        print(f"Saving Page with image: {self.image.name}")        super().save(*args, **kwargs)    def delete(self, *args, **kwargs):        print(f"Deleting Page with image: {self.image.name}")        image_name = self.image.name        try:            s3.delete(image_name)            print(f"Successfully deleted from S3: {image_name}")        except Exception as e:            print(f"Error deleting from S3: {e}")        super().delete(*args, **kwargs)