【问题标题】:How to automaticaly delete images linked to a page after deleting the page?删除页面后如何自动删除链接到页面的图像?
【发布时间】:2020-10-09 11:50:07
【问题描述】:

我有一个使用此模型的 Annonce 页面:

class AnnoncePage(Page):
    date = models.DateField("Date de publication", blank=True, null=True)
    description = RichTextField(features=['h2', 'h3', 'bold', 'italic', 'link', 'hr', 'ol', 'ul'], blank=True)
    lieu = models.CharField(blank=True, max_length=200)
    surface = models.PositiveSmallIntegerField(blank=True, null=True)
    nb_pieces = models.PositiveSmallIntegerField(blank=True, null=True)
    prix_affiché_index = models.CharField(blank=True, max_length=200, null=True)
    conditions_vente_et_prix = RichTextField(blank=True, features=['h2', 'h3', 'bold', 'italic', 'link', 'hr', 'ol', 'ul'])

    def main_image(self):
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        InlinePanel('gallery_images', label="Gallery images"),
        FieldPanel('lieu', classname="full"),
        FieldPanel('surface', classname="full"),
        FieldPanel('nb_pieces', classname="full"),
        FieldPanel('description', classname="full"),
        FieldPanel('prix_affiché_index', classname="full"),
        FieldPanel('conditions_vente_et_prix', classname="full")
    ]

    promote_panels = []
    settings_panels = []

    max_count = 20

class AnnoncePageGalleryImage(Orderable):
    page = ParentalKey(AnnoncePage, on_delete=models.SET_NULL, related_name='gallery_images', null=True)
    image = models.ForeignKey(
        'wagtailimages.Image', on_delete=models.SET_NULL, related_name='+', null=True
    )

    panels = [
        ImageChooserPanel('image')
    ]

如何在删除公告页面本身后自动删除公告页面的图像?我需要更换型号吗?

【问题讨论】:

  • AnnoncePageGalleryImage.page 上使用on_delete=models.CASCADE docs.djangoproject.com/en/3.1/ref/models/fields/…
  • @allcaps 即使在 AnnoncePageGalleryImage.page 上使用 on_delete=models.CASCADE,删除 AnnoncePage 实例后 AnnoncePage 图像仍然存在。
  • 数据库条目?还是磁盘上的文件?
  • @allcaps 删除 AnnoncePage 后,数据库中 annonce_annoncepagegalleryimage 条目被删除,但 wagttailimages_image 条目仍然存在。就像没有 CASCADE

标签: wagtail wagtail-admin


【解决方案1】:

Wagtail 图像对象可以在其他地方使用。自动删除这些内容可能会对其他内容产生令人讨厌的副作用。

您可以将delete 方法添加到AnnoncePage 或使用pre_delete 信号。您需要遍历所有相关的画廊图像并删除相关的 Wagtail 图像。 Django 将文件保留在磁盘上,因此您可能也想处理它。

class AnnoncePage(Page):
    ...
    def delete(self):
         for gallery_image in self.gallery_images.all():
              # Delete the file on disk here ...
              # After, delete the db obj.
              gallery_image.image.all().delete()
         self.gallery_images.all().delete()
         super().delete()

免责声明:未经测试的代码。

https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods https://docs.djangoproject.com/en/dev/ref/signals/#pre-delete https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.fields.files.FieldFile.delete

请注意,批量操作不会调用delete 方法和pre_delete 信号。您的里程可能会有所不同。

【讨论】:

  • 按照您的指示,我收到一个错误:异常类型:AttributeError at /admin/pages/34/delete/ 异常值:'DeferringRelatedManager' 对象没有属性'delete'
  • self.gallery_images.all().delete()
  • gallery_image.image.all().delete()
  • 您的新代码成功删除了图像,但它阻止了删除 AnnoncePage 本身。所以我也添加了`Page.objects.filter(id=self.id).delete()`这个delete方法。现在它可以按我的意愿工作了,谢谢
  • 太棒了!我们应该叫超级。这会在 Page 类上执行 delete 方法。
猜你喜欢
  • 2015-12-29
  • 2019-08-22
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多