当前位置: 首页 > 面试题库 >

Django上传:丢弃上传的重复项,使用现有文件(基于md5的检查)

邹山
2023-03-14
问题内容

我有一个带有的模型FileField,其中包含用户上传的文件。由于我想节省空间,因此我想避免重复。

我想要达到的目标:

  1. 计算 上传文件的 md5校验和
  2. 使用 基于其md5sum*文件名 存储文件 *
  3. 如果已经存在具有该名称的文件(新文件是 重复的 文件),则 丢弃上传的文件并改用现有文件

12 已经可以使用,但是 我该如何忘记上传的副本并使用现有文件呢?

请注意,我想 保留现有的文件 ,并 没有 覆盖它(主要是为了保持修改时间是相同的-更好的为备份)。

笔记:

  • 我正在使用Django 1.5
  • 上传处理程序为 django.core.files.uploadhandler.TemporaryFileUploadHandler

码:

def media_file_name(instance, filename):
    h = instance.md5sum
    basename, ext = os.path.splitext(filename)
    return os.path.join('mediafiles', h[0:1], h[1:2], h + ext.lower())

class Media(models.Model):
    orig_file = models.FileField(upload_to=media_file_name)
    md5sum = models.CharField(max_length=36)
    ...

    def save(self, *args, **kwargs):
            if not self.pk:  # file is new
                md5 = hashlib.md5()
                for chunk in self.orig_file.chunks():
                    md5.update(chunk)
                self.md5sum = md5.hexdigest()
            super(Media, self).save(*args, **kwargs)

任何帮助表示赞赏!


问题答案:

多亏了alTus的回答,我才知道编写
自定义存储类
是关键,而且比预期的要容易。

  • 我只是省略了调用超类_save方法来写文件(如果文件已经存在的话),而我只是返回名称。
  • 我覆盖get_available_name,以避免在文件名已经存在的情况下,在文件名后附加数字

我不知道这是否是 正确的 方法,但到目前为止效果很好。

希望这是有用的!

这是完整的示例代码

import hashlib
import os

from django.core.files.storage import FileSystemStorage
from django.db import models

class MediaFileSystemStorage(FileSystemStorage):
    def get_available_name(self, name, max_length=None):
        if max_length and len(name) > max_length:
            raise(Exception("name's length is greater than max_length"))
        return name

    def _save(self, name, content):
        if self.exists(name):
            # if the file exists, do not call the superclasses _save method
            return name
        # if the file is new, DO call it
        return super(MediaFileSystemStorage, self)._save(name, content)


def media_file_name(instance, filename):
    h = instance.md5sum
    basename, ext = os.path.splitext(filename)
    return os.path.join('mediafiles', h[0:1], h[1:2], h + ext.lower())


class Media(models.Model):
    # use the custom storage class fo the FileField
    orig_file = models.FileField(
        upload_to=media_file_name, storage=MediaFileSystemStorage())
    md5sum = models.CharField(max_length=36)
    # ...

    def save(self, *args, **kwargs):
        if not self.pk:  # file is new
            md5 = hashlib.md5()
            for chunk in self.orig_file.chunks():
                md5.update(chunk)
            self.md5sum = md5.hexdigest()
        super(Media, self).save(*args, **kwargs)


 类似资料:
  • 本文向大家介绍基于django和dropzone.js实现上传文件,包括了基于django和dropzone.js实现上传文件的使用技巧和注意事项,需要的朋友参考一下 1、dropzone.js http://www.dropzonejs.com/ dropzone.js是一个可预览\可定制化的文件拖拽上传,实现AJAX异步上传文件的工具 2、dropzone.js前端界面上传方式 官网下载 并且

  • 主要内容:上传图片对于Web应用程序,以便能够上传文件(资料图片,歌曲,PDF格式,文字......),它通常是很有用的。让我们在这一节中来讨论如何使用Django上传文件。 上传图片 在开始开发图片上传之前,请确保Python的图像库(PIL)已经安装。现在来说明上传图片,让我们创建一个配置文件格式,在 myapp/forms.py - 正如你所看到的,这里的主要区别仅仅是 forms.ImageField。Im

  • Django 的文件上传 在学习完 Django 的 Form 模块后,我们就用最后一个常用的文件上传的场景来结束本部分的内容。 1. Django 的文件上传实验 同样,话不多说,我们先通过两个上传的例子来看看 Django 的上传功能。 实验1:简单文件上传 准备本地文件,upload.txt,上传到服务器的 /root/test/django 目录下; 准备模板文件,显示上传按钮: <for

  • 问题内容: 我想知道通过使用Django / Python的网络应用上传大小约为4GB的文件是否有任何后果?我记得在过去使用Java进行流式上传是首选方法,但是今天还是这样吗?或者使用Django / Python这样做绝对安全吗? 问题答案: Django默认情况下会将上传的文件数据小于2.5MB放入内存中。较大的内容将被写入服务器目录,然后在传输完成时复制到整个服务器。可以自定义Django的

  • 本文向大家介绍基于WebUploader的文件上传js插件,包括了基于WebUploader的文件上传js插件的使用技巧和注意事项,需要的朋友参考一下 首先把地址甩出来,http://fex-team.github.io/webuploader/  里面有比较完整的demo案例文档,本文主要是基于文件上传和图片上传增加了大量的注释,基本保证了每行代码都有注释以助于理解,是对官网demo的增强版,希

  • 本文向大家介绍基于Spring实现文件上传功能,包括了基于Spring实现文件上传功能的使用技巧和注意事项,需要的朋友参考一下 本小节你将建立一个可以接受HTTP multi-part 文件的服务。 你将建立一个后台服务来接收文件以及前台页面来上传文件。 要利用servlet容器上传文件,你要注册一个MultipartConfigElement类,以往需要在web.xml 中配置<multipar