Uploading image to ImageField from BytesIO

时间:2015-07-28 16:46:47

标签: python django

I want upload a generated image directly in my model save without have to save it to file first.

Model:

avatar = models.ImageField(upload_to="img/", null=True, blank=True)

def save(self, *args, **kwargs):
    from .generate_avatar import Avatar
    self.avatar = Avatar.generate(128, self.display_name, "PNG")

This is my generate_avatar class.

def generate(cls, size, string, filetype="JPEG"):
    """
        Generates a squared avatar with random background color.

        :param size: size of the avatar, in pixels
        :param string: string to be used to print text and seed the random
        :param filetype: the file format of the image (i.e. JPEG, PNG)
    """
    render_size = max(size, Avatar.MIN_RENDER_SIZE)
    image = Image.new('RGB', (render_size, render_size),
                      cls._background_color(string))
    draw = ImageDraw.Draw(image)
    font = cls._font(render_size)
    text = cls._text(string)
    draw.text(cls._text_position(render_size, text, font),
              text,
              fill=cls.FONT_COLOR,
              font=font)
    stream = BytesIO()
    image = image.resize((size, size), Image.ANTIALIAS)
    image.save(stream, format=filetype, optimize=True)
    return stream.seek(0)

However, this does not work, no error just saves 0. Why?

1 个答案:

答案 0 :(得分:2)

To "simmulate" a file upload in django take a look at django's SimpleUploadedFile and do something like this :

from django.core.files.uploadedfile import SimpleUploadedFile

def save(self, *args, **kwargs)
    avatar = Avatar.generate(128, self.display_name, "PNG")
    self.avatar = SimpleUploadedFile(avatar.name, avatar.read())