Django 删除文件字段

2023-11-27

我正在 Django 中构建一个网络应用程序。我有一个上传文件的模型,但无法删除该文件。这是我的代码:

class Song(models.Model):
    name = models.CharField(blank=True, max_length=100)
    author = models.ForeignKey(User, to_field='id', related_name="id_user2")
    song = models.FileField(upload_to='/songs/')
    image = models.ImageField(upload_to='/pictures/', blank=True)
    date_upload = models.DateField(auto_now_add=True)

    def delete(self, *args, **kwargs):
        # You have to prepare what you need before delete the model
        storage, path = self.song.storage, self.song.path
        # Delete the model before the file
        super(Song, self).delete(*args, **kwargs)
        # Delete the file after the model
        storage.delete(path)

然后,在python manage.py shell我这样做:

song = Song.objects.get(pk=1)
song.delete()

它从数据库中删除记录,但不删除服务器上的文件。 我还能尝试什么?

Thanks!


在 Django 1.3 之前,当您删除相应的模型实例时,该文件会自动从文件系统中删除。您可能使用的是较新的 Django 版本,因此您必须自己从文件系统中删除该文件。

简单的基于信号的示例

我在撰写本文时选择的方法是混合使用post_delete and pre_save信号,这样每当删除相应模型或更改其文件时,就会删除过时的文件。

基于一个假设MediaFile model:

import os
import uuid

from django.db import models
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _


class MediaFile(models.Model):
    file = models.FileField(_("file"),
        upload_to=lambda instance, filename: str(uuid.uuid4()))


# These two auto-delete files from filesystem when they are unneeded:

@receiver(models.signals.post_delete, sender=MediaFile)
def auto_delete_file_on_delete(sender, instance, **kwargs):
    """
    Deletes file from filesystem
    when corresponding `MediaFile` object is deleted.
    """
    if instance.file:
        if os.path.isfile(instance.file.path):
            os.remove(instance.file.path)

@receiver(models.signals.pre_save, sender=MediaFile)
def auto_delete_file_on_change(sender, instance, **kwargs):
    """
    Deletes old file from filesystem
    when corresponding `MediaFile` object is updated
    with new file.
    """
    if not instance.pk:
        return False

    try:
        old_file = MediaFile.objects.get(pk=instance.pk).file
    except MediaFile.DoesNotExist:
        return False

    new_file = instance.file
    if not old_file == new_file:
        if os.path.isfile(old_file.path):
            os.remove(old_file.path)
  • 我认为我不久前构建的一个应用程序在生产中使用了此代码,但尽管如此,您仍需自行承担使用风险。
  • 例如,有一个可能的数据丢失场景:如果您的数据可能最终引用不存在的文件save()方法调用恰好位于回滚的事务内。您可以考虑将文件删除逻辑包装到transaction.on_commit(),沿着transaction.on_commit(lambda: os.remove(old_file.path)), 正如米哈伊尔评论中所建议的. django-cleanup图书馆沿着这些思路做一些事情.
  • 边缘情况:如果您的应用程序上传新文件并将模型实例指向新文件而不调用save()(例如通过批量更新QuerySet),旧文件将继续存在,因为信号不会运行。如果您使用传统的文件处理方法,则不会发生这种情况。
  • 编码风格:本例使用file作为字段名称,这不是一个好的样式,因为它与内置的冲突file对象标识符。

附录:定期清理

实际上,您可能想要also运行定期任务来处理孤立文件清理,以防运行时故障导致某些文件无法被删除。考虑到这一点,您可能可以完全摆脱信号处理程序,并执行这样的任务the处理不敏感数据和不太大文件的机制。

不管怎样,如果你are处理敏感数据时,最好仔细检查一下,确保及时删除生产中的数据,以避免承担任何相关责任。

See also

  • FieldFile.delete()在 Django 1.11 模型字段参考中(请注意,它描述了FieldFile类,但你会打电话.delete()直接在球场上:FileField实例代理到相应的FieldFile实例,并且您可以像访问字段一样访问其方法)

    请注意,删除模型时,相关文件不会被删除。如果您需要清理孤立文件,则需要自己处理(例如,使用可以手动运行或通过 cron 等安排定期运行的自定义管理命令)。

  • 为什么 Django 不自动删除文件:Django 1.3 发行说明中的​​条目

    在早期的 Django 版本中,当模型实例包含FileField被删除了,FileField它自己也从后端存储中删除了该文件。这为多种数据丢失场景打开了大门,包括回滚事务和引用同一文件的不同模型上的字段。在 Django 1.3 中,当模型被删除时FileField’s delete()方法不会被调用。如果您需要清理孤立文件,则需要自己处理(例如,使用可以手动运行或通过 cron 等安排定期运行的自定义管理命令)。

  • 使用示例pre_delete仅信号

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 删除文件字段 的相关文章

随机推荐

  • 如何在Android项目中使用ThreeTenABP

    我使用的是 Android Studio 2 1 2 我的 Java 设置如下 gt java version gt openjdk version 1 8 0 91 gt OpenJDK Runtime Environment build
  • Linq to Entities 中的动态 where 子句

    我正在使用 linq toEntity EF 我有一个带有 4 个字符串参数的构造函数 根据哪个参数不为空 我必须构建 linq 查询 我可以使用 if else 语句 但我还有其他带有 10 个参数的构造函数 在这种情况下 将会有很多组合
  • 在 SQL Server 上逐字使用 SOUNDEX()

    这是我的问题 例如我有一张桌子Products包含一个字段 Name Products ID Name 1 USB Key 10Go 2 Intel computer 3 12 inches laptop computer 我目前正在为 i
  • C# 中的 FlowDocument 内存问题

    我目前正在尝试解决释放 FlowDocument 资源的问题 我正在加载一个 rtf 文件并使用 TextRange Load 将其放入 FlowDocument 中 我注意到 在执行此操作后 它会保留这些资源 并且 GC 不会收集它 我运
  • 控制台应用程序中的 Twitter OAuth

    是否可以在不访问身份验证网页的情况下对 Twitter 控制台应用程序进行授权 我需要它 因为我正在开发可以从我们公司 Twitter 获取直接消息的应用程序 该控制台应用程序安排在 Web 服务器上 而不是由人类驱动 问候 阿列克谢 扎哈
  • 如何在 nhibernate 中复制和重试死锁

    查看我的日志 我可以看到我的应用程序很容易出现死锁 它们出现在我的应用程序的许多部分 1 有没有办法复制这个问题 即 我只在日志中看到过这一点 2 如果事务被锁定 重试的最佳 最简单方法是什么 3 如果我将调用包装在 try catch 中
  • 如何指定属性必须是(比如说)整数列表,而不仅仅是列表?

    使用属性库和 Python 3 6 我认为以下内容可以让我指定x and y只能包含整数 import attr attr s class C x List int attr ib not working y attr ib type Li
  • 内存目标 BTS 为何会比 load / BTS reg,reg / store 慢得多?

    在一般情况下 可以使用内存或寄存器操作数的指令如何会比内存操作数慢 mov mov gt 指令 gt mov mov 基于发现的吞吐量和延迟Agner Fog 的说明书 以我为例 查看 Skylake p238 我看到以下数字btr bts
  • Resharper 格式化链式方法

    R 中是否有设置将链接方法格式化为从实例化类的相同字符开始 我想要的是 var foo new FooDataBuilder WithDate myDate WithBar myBar Build R 给了我什么 var foo new F
  • 如何在 Windows 中注册自定义 URL 协议?

    如何向 Windows 注册自定义协议 以便在单击电子邮件或网页中的链接时打开我的应用程序并将 URL 中的参数传递给它 Go to Start然后在Find type regedit gt 它应该打开注册表编辑器 Click Right
  • ASP.NET MVC 获取视图的最后修改日期/文件信息

    我需要在工作申请的每一页上注明最后修改日期 我曾经通过在 WebForms 母版页底部包含对 的引用来实现此目的 该引用将返回当前 aspx 页面的上次修改日期 我的代码甚至会检查关联的 aspx cs 文件 比较上次修改日期 并返回最近的
  • .Net枚举winforms字体样式?

    我一直在寻找一种使用 Net 框架列出给定字体的有效字体样式的方法 即使我必须 pinvoke gdi32 或其他一些 API 因为并非所有字体都属于 System Drawing FontStyle 枚举值 粗体 斜体 常规 删除线 下划
  • 自定义WPF窗口样式

    我正在尝试制作自定义窗口样式 目标是创建一个可以被我的应用程序中的每个窗口使用的模板 模板包含工具栏 标题和 窗口将使用的区域 问题是 当我使用我的样式时 我无法再添加网格和控件 App xaml
  • 在 __init__ 上使用 scrapy 管道中的参数

    我有一个 scrapy pipelines py 我想获得给定的参数 在我的 Spider py 中 它工作得非常完美 class MySpider CrawlSpider def init self host domain id args
  • 从非托管代码调用托管 .NET 代码的最佳方法

    我试图找到从非托管 C 代码调用托管 NET 代码的最佳执行方法 我在我的 C 应用程序中找到了有关托管 NET 的信息 并且我能够创建 pRuntimeHost 并毫无问题地启动它 ExecuteInDefaultAppDomain 似乎
  • 如何让 iOS 上的 tesseract 运行得更快?

    我在 ios 上的 tesseract ocr 上遇到了困难 一切工作正常 但速度真的很慢 单行数字的识别时间为 2 3 秒 我正在阅读视频流 我正在使用 tesseract 3 01 以及针对我的字体的自定义训练文件 这是我所做的 设置
  • Rails 3 中控制器特定的样式表:继承

    首先 我是 Rails 的新手 我正在 Rails 网站上工作 它有三个控制器 即application controller static pages controllers 和 users controller 它们在 app asse
  • 在 Hibernate 验证期间执行 EntityManager 查询的正确方法

    我是一个 Java EE EJB 菜鸟 但从我收集的文档和其他帖子来看 您无法在实体验证期间使用相同的实体管理器 会话查询数据库 一般来说 可移植应用程序的生命周期方法不应调用 EntityManager 或查询操作 访问其他实体实例或修改
  • Haskell 和惰性 Monads 评估

    在使用 monad 时 我经常遇到评估问题 现在 我了解了延迟求值的基本概念 但我不明白如何在 Haskell 中延迟求值 monad 考虑下面的代码 module Main where import Control Monad impor
  • Django 删除文件字段

    我正在 Django 中构建一个网络应用程序 我有一个上传文件的模型 但无法删除该文件 这是我的代码 class Song models Model name models CharField blank True max length 1