类似StringIO,扩展了django.core.files.File

joo*_*zek 6 python django

class MyModel(models.Model)
 image = models.FileField(upload_to="blagh blagh...")
 #more spam...
Run Code Online (Sandbox Code Playgroud)

我在内存中有一个文件,我想通过Django FileField保存方法保存它,如下所示:

photo.image.save(name, buffer) # second arg should be django File
Run Code Online (Sandbox Code Playgroud)

我曾尝试使用StringIO,但它没有扩展django.core.files.File,因此没有实现方法块().我把它包装在这样的File对象中:

buffile = File(buffer, name) # first argument should be a file
photo.image.save(name, buffile)
Run Code Online (Sandbox Code Playgroud)

但File方法使用提供的文件的大小和名称字段.StringIO不定义它们.我发现了这个,但链接已经死了

小智 28

您可以使用ContentFile而不是File

from django.core.files.base import ContentFile

photo.image.save(name, ContentFile(buffer))
Run Code Online (Sandbox Code Playgroud)

  • 整齐!这比我的解决方案简单得多...... + 1 (3认同)
  • 如果缓冲区是一个“StringIO”对象,您将需要执行“ContentFile(buffer.getvalue())” (3认同)

s29*_*s29 8

Re Jason的回答.请注意,ContentFile只接受字符串,而不接受任何类文件对象.这是一个 -

from django.core.files.base import *

class StreamFile(ContentFile):
    """
    Django doesn't provide a File wrapper suitable 
    for file-like objects (eg StringIO)
    """
    def __init__(self, stream):
        super(ContentFile, self).__init__(stream)
        stream.seek(0, 2)
        self.size = stream.tell()
Run Code Online (Sandbox Code Playgroud)

现在你可以做这样的事情 -

photo.image.save(name, StreamFile(io))
Run Code Online (Sandbox Code Playgroud)


elo*_*0ka 7

如果你有一个字节流,你想保存到FileField/ImageField,这里有一些可能有用的代码:

>>> from django.core.files.uploadedfile import InMemoryUploadedFile
>>> from cStringIO import StringIO
>>> buf = StringIO(data)  # `data` is your stream of bytes
>>> buf.seek(0, 2)  # Seek to the end of the stream, so we can get its length with `buf.tell()`
>>> file = InMemoryUploadedFile(buf, "image", "some_filename.png", None, buf.tell(), None)
>>> photo.image.save(file.name, file)  # `photo` is an instance of `MyModel`
>>> photo.image
<ImageFieldFile: ...>
Run Code Online (Sandbox Code Playgroud)

一些说明:

  • 您可以为图像组合您想要的任何名称,但您可能希望保持扩展准确
  • 第二个参数InMemoryUploadedFile是模型中字段的名称,因此是"图像"

这有点吝啬,但它完成了工作.希望API能够在1.3/4中得到更多清理.

编辑:尽管你仍然想知道图像的文件名,但
请参阅Jason的答案以获得更简单的方法.