Django在保存图像之前获取ImageField路径 [英] Django get ImageField path before saving image

查看:2173
本文介绍了Django在保存图像之前获取ImageField路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用chunks方法保存图像来处理用户尝试上传大图像的情况:

I'm trying to save an image using the chunks method to handle the case where a user tries to upload a large image:

destination = open(incident.Image.path, 'wb+')
for chunk in request.FILES['image'].chunks():
    destination.write(chunk)
destination.close()

我的问题是我无法获取文件路径,图像字段如下所示:

My problem is I can't get the filepath without first saving something in the Image field like so:

fileName = str(int(time.time() * 1000))
imageName = fileName + '.jpg'
incident.Image.save(imageName, request.FILES['image'])

我的问题是如何获得相当于事件.Image.path,而不保存图像?我不想硬编码路径,而我被卡住的原因是因为我无法获取完整的文件路径,而没有获取ImageField声明的upload_to部分

My question is how can I get the equivalent of incident.Image.path without first saving the image? I don't want to hardcode the path, and the reason I'm stuck is because I can't get the full filepath without getting the upload_to portion of the ImageField declaration

编辑:

好的,我有一点更远了,但我又被困住了:

Ok, I've gotten a little farther but I'm stuck again:

imgBuffer = StringIO.StringIO()
for chunk in request.FILES['image'].chunks():
    imgBuffer.write(chunk)

# rotate it
rotate = request.POST['rotation']
im = Image.open(imgBuffer)
im = im.rotate(float(rotate))

incident.Image.save(imageName, ContentFile(imgBuffer))


$ b $我得到的IOError无法识别im = Image.open(imgBuffer)中抛出的图像文件,任何想法?

I'm getting IOError cannot identify image file which is thrown at im = Image.open(imgBuffer), any ideas?

推荐答案

图像(作为文件)保存在模型字段的 pre_save 方法中。这是一个工作示例(从我的项目获得)一个这样的自定义模型字段 - FixedImageField

Images (as files) are saved in pre_save method of model fields. Here is a working example (got from my project) of a such custom model field - FixedImageField.

你可能会看到我如何检索图像函数 pre_save 中的路径。

You may see how I retrieve an image path in the function pre_save.

在我的情况下,我有一个复杂的方案(我必须继承图像字段),但可以简化您可以实现自己的_save_fixed_resolution_image(块,路径) - 在我的情况下,它将图像转换为最大400x400大小的图像:

In my case I have a complicated scheme (I have to inherit the image field) but you can simplify it for your case.



You can implement your own _save_fixed_resolution_image(chunks,path) - in my case it transforms an image to an image with maximum 400x400 size:

from PIL import Image
import StringIO
from yourproject.settings import MEDIA_ROOT
import os
from django.db import models

class ChunksImageField( models.ImageField ):    
    def pre_save( self, model_instance, add ):
        file = super( models.FileField, self ).pre_save(model_instance, add)
        if file and not file._committed:
            if callable( self.upload_to ):
                path = self.upload_to( model_instance, "" )
            else:
                path = self.upload_to
            file.name = path
            full_path = os.path.join( MEDIA_ROOT, path )
            chunks = _get_chunks( file.chunks() )
            self._save_image_func( model_instance, chunks, full_path )

        return file

class FixedImageField( ChunksImageField ):
    def __init__( self, *args, **kwargs ):
        super( FixedImageField, self ).__init__( *args, **kwargs )

    def _save_image_func( self, model_instance, chunks, path ):
        _save_fixed_resolution_image( chunks, path )

def _save_fixed_resolution_image( chunks, out_file_path ):
    image = _get_image( chunks )

    if image.size[ 0 ] > _image_max_size or image.size[ 1 ] > _image_max_size:
        image.thumbnail( ( _image_max_size, _image_max_size, ) )

    save_image( image, out_file_path )

def save_image( image, out_file_path ):
    image.save( out_file_path, "JPEG", quality = 100 )

def _get_chunks( chunks ):
    chunks_ = ""
    for chunk in chunks:
        chunks_ += chunk
    return chunks_

如何在您的模型中使用它:


How to use it in your model:

class YourModel( models.Model ):
    image = FixedImageField( upload_to = image_path ) # substitute your image path here

这篇关于Django在保存图像之前获取ImageField路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆