【问题标题】:Copy/move linked file when changing model instance owner in Django admin在 Django admin 中更改模型实例所有者时复制/移动链接文件
【发布时间】:2017-02-09 10:27:02
【问题描述】:

我有一个非常简单的图像模型

class Image(Model):
    owner = ForeignKey(User)
    img = ImageField(upload_to=image_file_path)

image_file_path 解析为 <username>/images/,其中 username 是 Image 模型实例的 owner.username

现在,当使用 Django admin 更改图像的所有者时,我希望将物理图像文件移动到适当的路径,即<new_username>/images/

最简单/“正确”的方法是什么?

编辑:

尝试了一下之后的一些想法

  • post_save handlers:这个想法是通过在模型更改后将文件移动到正确的位置来确保模型是健全的。问题是,如果发生了一些不好的事情——文件丢失/传输错误(例如,如果存储在 S3 上并且连接不好)/等等——那么你可能会陷入循环尝试恢复更改或结束模型/FS 状态不一致

  • Django 管理员操作:这似乎是一种更安全的方法,因为您可以只复制文件,检查它是否正常,然后更改模型,检查它是否正常,然后删除旧文件。如果出现任何问题,您可以中止,因为这是从管理界面手动启动的,所以用户不会遇到不一致的行为。

  • pre_save:与“Django 管理操作”相同的过程可能与pre_save 一起使用,但如果您因问题而中止,那么用户体验会受到影响。另一方面,如果复制/移动文件失败,用户将无法上传任何内容。

还有第四种方法吗? Django 中的模型有消毒剂吗?

【问题讨论】:

    标签: django django-models django-admin


    【解决方案1】:

    使用 Image 模型的post_save 信号。同理可以在删除记录时使用post_delete实际删除图片文件。

    您可以查看信号文档here

    【讨论】:

    • post_save 的问题是,如果文件传输不通过,我必须恢复模型更改以保持一切正常。反转触发另一个post_save -> 可能的循环
    • @Timo 是否在图像传输失败时运行 post_save?这似乎不直观......但如果是这样,您总是可以在尝试移动它之前添加额外的检查以查看图像是否存在于您期望的位置,
    • 所有者更改触发了仅更改所有者的保存,我希望图像路径(在模型实例和磁盘上)反映此更改。在 post_save 处理程序中移动/复制图像可能会失败,然后我的状态不一致 -> 需要恢复所有者更改 -> 可能会陷入循环。
    • @Timo 在这种情况下,您可能需要考虑创建自定义 create() 方法。
    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多