【问题标题】:Django - Delete file associated with ImageField attribute of ModelDjango - 删除与模型的 ImageField 属性关联的文件
【发布时间】:2022-01-11 06:23:30
【问题描述】:

所以我有一个名为User 的模型,它有一个avatar 字段,它只是用户的头像。每当用户选择删除他们的头像时,我希望能够删除该文件。正如您在下面的view.py 中看到的那样,我从request 检索当前用户对象(这是因为我从给出的访问令牌中获取用户uuid 以发出请求,然后查询用户对象)。然后我在avatar 属性上调用delete,但我不知道这是否真的也删除了文件。我的假设是它只是删除了该属性url删除模型中的 ImageField 属性时,如何删除与 ImageField 关联的文件?

model.py

class User(AbstractDatesModel):
    uuid = models.UUIDField(primary_key=True)
    username = models.CharField(max_length=USERNAME_MAX_LEN, unique=True, validators=[
        MinLengthValidator(USERNAME_MIN_LEN)])
    created = models.DateTimeField('Created at', auto_now_add=True)
    updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True)
    avatar = models.ImageField(upload_to=avatar_directory_path, blank=True, null=True)

view.py

@api_view(['POST', 'DELETE'])
def multi_method_user_avatar(request):
    if request.method == 'POST':
        # Some POST code
    elif request.method == 'DELETE':
        try:
            request.user.avatar.delete()
            request.user.save()

            return Response(status=status.HTTP_204_NO_CONTENT)
        except Exception as e:
            return Response(dict(error=str(e), user_message=generic_error_user_msg),
                            status=status.HTTP_400_BAD_REQUEST)

【问题讨论】:

  • 这能回答你的问题吗? Django delete FileField
  • @HaoLan 是的,我会这么说,但下面的人给出了更快更直接的答案。
  • 我只想告诉你,在提出问题之前尝试搜索问题。
  • 而做os.remove不是一个好方法,如果你使用其他文件系统,而不是本地文件系统,比如对象存储。
  • @HaoLan 我搜索过。我只是不确定 ImageFileField 和 FileField 之间是否存在不同的复杂性。例如,也许 ImageFileField 内置了删除文件的功能。

标签: python django


【解决方案1】:

request.user.avatar.delete() 足够了。我运行了一个测试,在调用该端点之前检查文件是否存在,并在调用端点后被删除并且它通过了。使用os.remove 不适用于已部署的服务器,因为您无权访问该级别的文件系统。

【讨论】:

    【解决方案2】:

    删除 ImageField 会将文件保留在系统中。

    将您的代码更改为此以删除文件:

    #insert at top of file
    import os
    
    elif request.method == 'DELETE':
        try:
            os.remove(request.user.avatar.path)
            request.user.avatar.delete()
            request.user.save()
    

    【讨论】:

    • 对不起,我必须取消选择这个作为答案,当您将 Django 应用程序连接到 S3 时,这不起作用,因为您没有对 S3 的操作系统访问权限
    • 您的问题并不是说图像在 S3 存储桶上。
    • 是的,很抱歉,这很明显,因为您通常会部署一个站点。
    • 即使有这个假设,CDN 也比 S3 多
    • 只需将 os.remove() 替换为用于删除文件的 S3 API。
    猜你喜欢
    • 2020-12-20
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    相关资源
    最近更新 更多