不要将模型保存在重复文件上 - Django 2

2024-01-25

我正在尝试检查现有文件并覆盖它,到目前为止我可以使用自定义存储来完成此操作,如下所示

from django.core.files.storage import FileSystemStorage

class DuplicateFileStorage(FileSystemStorage):

    def get_available_name(self, name, max_length=None):

        return name

    def _save(self, name, content):
        if self.exists(name):
            self.delete(name)

        return super(DuplicateFileStorage, self)._save(name, content)

上面的类检查现有文件并将其删除。

它所关注的模型是:

class DataStorageModel(models.Model):

    user = models.ForeignKey(User, related_name='data_storage', on_delete=models.CASCADE)
    file_name = models.CharField(blank=True, max_length=200, help_text="File Name")
    file = models.FileField(blank=True, null=True, upload_to=user_directory_path, storage=DuplicateFileStorage())
    relative_path = models.CharField(blank=True, max_length=200, help_text="Relative Path if folder else null")

    def delete(self, using=None, keep_parents=False):

        self.file.delete()

        return super(DataStorageModel, self).delete()

问题是,虽然它删除并写入相同的文件,但它也会创建一个具有相同现有路径的新模型条目,也就是说,如果我上传相同的文件两次,我会在操作系统路径中得到一个文件,但会得到两个模型条目。像这样的东西(这里有一张图片):

所以我尝试使用clean()方法与self.file.storage.exists(self.file.name)(根据this https://stackoverflow.com/questions/50606068/how-to-ensure-file-exists-in-django-project)但我得到的存在是False,即使那里有一个文件。

def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):

    self.full_clean()

    return super(DataStorageModel, self).save()

def clean(self):

    print(self.file.storage.exists(self.file.name))  # <--- False

所以我的问题是,我应该如何检查是否存在重复文件,覆盖该文件但不创建新记录?

Edit

我忘记输入user_director_path():

def user_directory_path(instance, filename):
    """
    If relative path is not ``null`` the files will be stored as is else it will be
    stored to the root directory.
    """

    if instance.relative_path != 'null':
        return 'user_{0}{1}'.format(instance.user.id, instance.relative_path)
    return 'user_{0}/{1}'.format(instance.user.id, filename)

我想如果我这样做我就明白了:

def clean_fields(self, exclude=None):

    if self.file.storage.exists('user_{0}{1}'.format(self.user.id, self.relative_path)):
        raise ValidationError('File already exists.')

它可以工作,但整个上传失败,甚至无法重写文件


条件,if instance.relative_path != 'null':是错的。应该只是if instance.relative_path:

当我尝试你的片段时,我觉得有问题user_directory_path功能。所以,我将其更改为如下所示。

def user_directory_path(instance, filename):
    """
    If relative path is not ``null`` the files will be stored as is else it will be
    stored to the root directory.

    The "relative_path" path should not be start or ends with a slash ("/") but, can use slash inside

    /foo/ -> Not allowed
    /foo/bar -> Not allowed
    foo/bar/ -> Not allowed

    foo -> Allowed
    foo/bar -> Allowed
    foo/bar/foobar -> Allowed

    """

    if instance.relative_path:
        relative_path = instance.relative_path
        if relative_path[0] == '/':
            relative_path = relative_path[1:]
        if relative_path[:-1] == '/':
            relative_path = relative_path[:-1]

        return 'user_{0}/{1}/{2}'.format(instance.user.id, relative_path, filename)
    return 'user_{0}/{1}'.format(instance.user.id, filename)

现在谈到我们的解决方案,我创建了一个示例视图来解决该问题。

from django.http.response import HttpResponse


def foo(request):
    if request.method == 'POST':
        create_data = {
            "user_id": request.user.pk,
            "file": request.FILES['file_name']
        }

        ds_temp = DataStorageModel(**create_data)
        path = user_directory_path(ds_temp, ds_temp.file.name)
        try:
            ds_existing = DataStorageModel.objects.get(file=path)
            ds_existing.file = create_data['file']
            ds_existing.save()
            return HttpResponse("instance modified")
        except DataStorageModel.DoesNotExist:
            ds_temp.save()
            return HttpResponse("new instance created")
    return HttpResponse("HTTP GET method")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不要将模型保存在重复文件上 - Django 2 的相关文章

  • 将 numpy 数组合并为单个 int

    numpy 数组怎么可以这样 10 22 37 45 转换为单个 int32 数字 如下所示 10223745 这可以工作 gt gt gt int join map str 10 22 37 45 10223745 基本上你使用map s
  • 按边距(“全部”)值列对 Pandas 数据透视表进行排序

    我试图根据 pandas 数据透视表中的行总和对最后一列 边距 aggrfunc 进行降序排序 我知道我在这里错过了一些简单的东西 但我无法弄清楚 数据框 数据透视表 WIDGETS DATE 2 1 16 2 2 16 2 3 16 Al
  • Matplotlib:如何有效地将大量线段着色为独立渐变

    Python 绘图库 如何有效地将大量线段着色为独立渐变 已经 阅读this https stackoverflow com questions 8500700 how to plot a gradient color line in ma
  • 如何过滤 Pandas GroupBy 对象并获取 GroupBy 对象?

    当对 Pandas groupby 操作的结果执行过滤时 它返回一个数据帧 但假设我想执行进一步的分组计算 我必须再次调用 groupby 这似乎有点绕 有更惯用的方法吗 EDIT 为了说明我在说什么 我们无耻地从 Pandas 文档中窃取
  • 创建上下文后将 jar 文件添加到 pyspark

    我正在笔记本上使用 pyspark 并且不处理 SparkSession 的创建 我需要加载一个包含一些我想在处理 rdd 时使用的函数的 jar 您可以使用 jars 轻松完成此操作 但在我的特定情况下我无法做到这一点 有没有办法访问sp
  • 类型错误:需要二进制或 unicode 字符串,得到 618.0

    I ve been trying to implement this ML Linear Model into my dataset https www tensorflow org tutorials estimator linear L
  • 运行 Python 单元测试,以便成功时不打印任何内容,失败时仅打印 AssertionError()

    我有一个标准单元测试格式的测试模块 class my test unittest TestCase def test 1 self tests def test 2 self tests etc 我的公司有一个专有的测试工具 它将作为命令行
  • 根据其他单元格值更改多个单元格值

    我想更改包含的单元格moving to movingToOpenor movingToClose基于下一个单元格中给出的状态 有时循环会被中断并且不会从open to close or close to open 这是我当前的数据框 Dat
  • 是否需要关闭没有引用它们的文件?

    作为一个完全的编程初学者 我试图理解打开和关闭文件的基本概念 我正在做的一项练习是创建一个脚本 允许我将内容从一个文件复制到另一个文件 in file open from file indata in file read out file
  • Ubuntu systemd 自定义服务因 python 脚本而失败

    希望获得有关 Ubuntu 中的 systemd 守护进程服务的一些帮助 我写了一个 python 脚本来禁用 Dell XPS 上的触摸屏 这更像是一个问题 而不是一个有用的功能 该脚本可以工作 但我不想一直启动它 这就是为什么我想到编写
  • 在骨架图像中查找线 OpenCV python

    我有以下图片 我想找到一些线来进行一些计算 平均长度等 我尝试使用HoughLinesP 但它找不到线 我能怎么做 这是我的代码 sk skeleton mask rows cols sk shape imgOut np zeros row
  • 使用另一个数据帧在数据帧中创建子列

    我对 python 和 pandas 很陌生 在这里 我有一个以下数据框 did features offset word JAPE feature manual feature 0 200 0 aa 200 200 0 200 11 bf
  • 检测是否从psycopg2游标获取?

    假设我执行以下命令 insert into hello username values me 我跑起来就像 cursor fetchall 我收到以下错误 psycopg2 ProgrammingError no results to fe
  • 使用 PIL 在 Tkinter 中显示动画 GIF

    我正在尝试制作一个程序来使用 Tkinter 显示动画 GIF 这是我最初使用的代码 from future import division Just because division doesn t work right in 2 7 4
  • 如何在亚马逊 EC2 上调试 python 网站?

    我是网络开发新手 这可能是一个愚蠢的问题 但我找不到可以帮助我的确切答案或教程 我工作的公司的网站 用 python django 构建 托管在亚马逊 EC2 上 我想知道从哪里开始调试这个生产站点并检查存储在那里的日志和数据库 我有帐户信
  • AWS Lambda 不读取环境变量

    我正在编写一个 python 脚本来查询 Qualys API 中的漏洞元数据 我在 AWS 中将其作为 lambda 函数执行 我已经在控制台中设置了环境变量 但是当我执行函数时 出现以下错误 module initialization
  • 如何给URL添加变量?

    我正在尝试从网站收集数据 我有一个 Excel 文件 其中包含该网站的所有不同扩展名 F i www example com example2 我有一个脚本可以成功从网站中提取 HTML 但现在我想为所有扩展自动执行此操作 然而 当我说 s
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • IndexError - 具有匀称形状的笛卡尔 PolygonPatch

    我曾经使用 shapely 制作一个圆圈并将其绘制在之前填充的图上 这曾经工作得很好 最近 我收到索引错误 我将代码分解为最简单的操作 但它甚至无法执行最简单的循环 import descartes import shapely geome
  • 用于插入或替换 URL 参数的 Django 模板标签

    有人知道 Django 模板标签可以获取当前路径和查询字符串并插入或替换查询字符串值吗 例如向 some custom path q how now brown cow page 3 filter person 发出请求 电话 urlpar

随机推荐