save()生成重复的文件

时间:2022-04-24 19:20:47

I have user submitted content that I am trying to write to a file and then save to a FileField.

我将用户提交的内容尝试写入文件,然后保存到文件字段。

so I have a model that looks like this:

我有一个这样的模型

class Revision(models.Model):
    def custom_revision_file_path(instance, filename):
        return '/'.join(['content/revisions', filename])
    path = models.FileField(upload_to=custom_revision_file_path)
    document = models.ForeignKey(Document)
    ...

and the view that creates the instance looks like this:

创建实例的视图是这样的:

def handle_revisions(request): 
    document = Document.objects.get(id=request.GET['docid'])
    basename = os.path.basename(str(document.path))

    revision = Revision.objects.create(
        document = document,
    )
    revision.path.save(basename, ContentFile(request.GET['revision']))

This all works relatively fine but for two problems:

这一切都相对正常,但有两个问题:

1) the ContentFile puts a space between each letter in my string so 'test' turns into 't e s t' ;

1)ContentFile在我的字符串中每个字母之间放一个空格,这样“test”就变成了“te”;

2) for some reason each time I run the view two Revision instances are saved with roughly the same path. ie. one path will be 'content/revisions/test.txt' and the other will be 'content/revisions/test_1.txt' when the second one shouldn't exist at all.

2)出于某种原因,每次运行视图时,都会以大致相同的路径保存两个修订实例。ie。一个路径是“内容/修订/测试”。txt和另一个将是“内容/修订/test_1”。当第二个不应该存在的时候。

What gives?

到底发生了什么事?

1 个解决方案

#1


2  

First of all, you should never use something like that to create a path :

首先,你不应该使用这样的东西来创建路径:

'/'.join(['content/revisions', filename])

but :

但是:

os.path.join("my_dir", "my_subdir", ..., "filename.txt")

You are not supposed to know if your application runs on Unix-like or on Windows (yes, some people use Windows as webserver).

您不应该知道您的应用程序是在unix上运行还是在Windows上运行(是的,有些人使用Windows作为webserver)。

Also, you should not call your FileField attribute path, this is ambiguous with FilePathField.

此外,不应该调用FileField属性路径,这与FilePathField是不明确的。

Is this field NOT NULL ? Because in your create() statement you don't provide one. This should raise an Error.

这个字段不是空的吗?因为在create()语句中不提供。这将引起错误。

I don't get this :

我不明白

revision.path.save(basename, ContentFile(request.GET['revision']))

What are you trying to achieve ? Are you sure you want to store a GET parameter in the file ?

你想达到什么目的?您确定要在文件中存储GET参数吗?

To answer your question, by default, Django does not take the responsability to overwrite a file that exists on your filesystem, this is why it automatically store it with an unique path by adding a suffix.

为了回答您的问题,默认情况下,Django没有响应能力覆盖存在于文件系统上的文件,这就是为什么它通过添加后缀自动以唯一路径存储它。

If this behaviour does not fits, consider writing a custom file storage.

如果这种行为不适合,考虑编写自定义文件存储。

#1


2  

First of all, you should never use something like that to create a path :

首先,你不应该使用这样的东西来创建路径:

'/'.join(['content/revisions', filename])

but :

但是:

os.path.join("my_dir", "my_subdir", ..., "filename.txt")

You are not supposed to know if your application runs on Unix-like or on Windows (yes, some people use Windows as webserver).

您不应该知道您的应用程序是在unix上运行还是在Windows上运行(是的,有些人使用Windows作为webserver)。

Also, you should not call your FileField attribute path, this is ambiguous with FilePathField.

此外,不应该调用FileField属性路径,这与FilePathField是不明确的。

Is this field NOT NULL ? Because in your create() statement you don't provide one. This should raise an Error.

这个字段不是空的吗?因为在create()语句中不提供。这将引起错误。

I don't get this :

我不明白

revision.path.save(basename, ContentFile(request.GET['revision']))

What are you trying to achieve ? Are you sure you want to store a GET parameter in the file ?

你想达到什么目的?您确定要在文件中存储GET参数吗?

To answer your question, by default, Django does not take the responsability to overwrite a file that exists on your filesystem, this is why it automatically store it with an unique path by adding a suffix.

为了回答您的问题,默认情况下,Django没有响应能力覆盖存在于文件系统上的文件,这就是为什么它通过添加后缀自动以唯一路径存储它。

If this behaviour does not fits, consider writing a custom file storage.

如果这种行为不适合,考虑编写自定义文件存储。