Django get ImageField path before saving image

不想你离开。 提交于 2020-01-05 09:14:25

问题


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

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

EDIT:

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

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


回答1:


Have a look at stringIO also have a look at this site




回答2:


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.

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

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



回答3:


I solved the primary problem as follows:

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

The secondary problem of not uploading twice I did as follows:

filename = os.path.basename(url)
myimage.myimagefield = os.path.join(upload_to, filename)
myimage.save()


来源:https://stackoverflow.com/questions/10949601/django-get-imagefield-path-before-saving-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!