Django在保存图像之前获取图像字段路径

Django在保存图像之前获取图像字段路径,django,django-models,Django,Django Models,我尝试使用chunks方法保存图像,以处理用户尝试上载大图像的情况: destination = open(incident.Image.path, 'wb+') for chunk in request.FILES['image'].chunks(): destination.write(chunk) destination.close() 我的问题是,如果不先在图像字段中保存某些内容,我就无法获取文件路径,如下所示: fileName = str(int(time.time() *

我尝试使用chunks方法保存图像,以处理用户尝试上载大图像的情况:

destination = open(incident.Image.path, 'wb+')
for chunk in request.FILES['image'].chunks():
    destination.write(chunk)
destination.close()
我的问题是,如果不先在图像字段中保存某些内容,我就无法获取文件路径,如下所示:

fileName = str(int(time.time() * 1000))
imageName = fileName + '.jpg'
incident.Image.save(imageName, request.FILES['image'])
我的问题是,如何在不首先保存图像的情况下获得event.Image.path的等效值?我不想硬编码路径,我被卡住的原因是,如果不获得ImageField声明的upload_部分,我无法获得完整的文件路径

编辑:

好吧,我走得更远了一点,但我又被卡住了:

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

我收到IOError无法识别在im=image.open(imgBuffer)中抛出的图像文件,有什么想法吗?

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

您可以看到我如何在函数pre_save中检索图像路径

在我的例子中,我有一个复杂的方案(我必须继承图像字段),但是你可以根据你的情况简化它

您可以实现自己的_save_fixed_resolution_image(块,路径)-在我的例子中,它将图像转换为最大尺寸为400x400的图像:

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_
如何在您的模型中使用它:

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

我解决了主要问题如下:

myimage = MyImageModel()
upload_to = myimage.myimagefield.field.upload_to
filepath = os.path.join(settings.MEDIA_ROOT, upload_to)
filename = os.path.basename(url)
myimage.myimagefield = os.path.join(upload_to, filename)
myimage.save()
第二个问题是没有上传两次,我的做法如下:

myimage = MyImageModel()
upload_to = myimage.myimagefield.field.upload_to
filepath = os.path.join(settings.MEDIA_ROOT, upload_to)
filename = os.path.basename(url)
myimage.myimagefield = os.path.join(upload_to, filename)
myimage.save()

他仍然需要向磁盘写入两次,这正是我试图避免的。我有一个上传和保存图片的方法,我只是想通过不写两次来加快上传和保存的速度。事实上,没关系,这可能会奏效。他必须向磁盘写两次,但我看不出有什么办法可以避免。我想我是在寻找一个不必这样做的选项。你应该能够阻止它,因为StringIO允许你以字符串形式存储文件。我在想直接上传文件到数据库的地方使用过它。在保存到磁盘之前,您甚至可以使用它浏览PIL。您的
\u get\u image(chunks)
功能看起来如何?