代码之家  ›  专栏  ›  技术社区  ›  joozek

一个类似StringIO的类,它扩展了django.core.files.File

  •  6
  • joozek  · 技术社区  · 16 年前
    class MyModel(models.Model)
     image = models.FileField(upload_to="blagh blagh...")
     #more spam...
    

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

    photo.image.save(name, buffer) # second arg should be django File
    

    我尝试过使用StringIO,但它没有扩展django.core.files.File,因此没有实现chunks()方法。我把它包装成这样一个文件对象:

    buffile = File(buffer, name) # first argument should be a file
    photo.image.save(name, buffile)
    

    this ,但链接已断开

    4 回复  |  直到 9 年前
        1
  •  7
  •   Community Mohan Dere    9 年前

    如果您有一个字节流,希望将其保存到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: ...>
    

    注意事项:

    • 第二个论点 InMemoryUploadedFile

    有点费劲,但它能完成任务。希望API在1.3/4中得到更多的清理。


    看到了吗 Jason's answer 更简单的方法是,您仍然需要知道图像的文件名。

        2
  •  34
  •   Jason    16 年前

    可以使用ContentFile而不是File

    from django.core.files.base import ContentFile
    
    photo.image.save(name, ContentFile(buffer))
    
        3
  •  8
  •   s29    15 年前

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

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

    photo.image.save(name, StreamFile(io))