Django FileField.save() 生成重复文件

发布于 2024-12-23 07:38:41 字数 958 浏览 3 评论 0原文

我有用户提交的内容,我试图将其写入文件,然后保存到 FileField

所以我有一个看起来像这样的模型

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)
    ...

并且创建实例的视图看起来像这样:

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']))

这一切都工作得相对很好,但有两个问题:

1) >ContentFile 在字符串中的每个字母之间放置一个空格,因此 'test' 变成 'tes t'

2)出于某种原因,每次我运行视图时,两个 Revision 实例都会以大致相同的路径保存。 IE。当第二个路径不应存在于全部。

什么给?

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' ;

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.

What gives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纵情客 2024-12-30 07:38:41

首先,您永远不应该使用类似的东西来创建路径:

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

但是:

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

您不应该知道您的应用程序是在类Unix上运行还是在Windows上运行(是的,有些人使用 Windows 作为网络服务器)。

另外,您不应该调用 FileField 属性 path,这与 FilePathField 不明确。

该字段是NOT NULL吗?因为在您的 create() 语句中您没有提供。这应该会引发错误。

我不明白:

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

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

为了回答你的问题,默认情况下,Django 不承担覆盖文件系统上存在的文件的责任,这就是为什么它会自动将其存储为 唯一路径通过添加后缀。

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

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).

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

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

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 ?

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文