尝试使用Azure存储在Django中获取image.size时出现NotImplementedError

时间:2016-02-01 01:42:34

标签: python django azure azure-storage azure-storage-blobs

在Django的forms.py中,我有一个特定的代码片段,我在上传前清理图像。相关摘录是:

from PIL import Image, ImageFile

class UserProfileForm(forms.ModelForm):
    avatar = forms.ImageField(label='Upload Photo')
    class Meta:
        model = UserProfile
        exclude = ('user','previous_retort')   
        fields=('avatar',)


    def clean_avatar(self):
        image=self.cleaned_data.get("avatar")
        if image:
            try:
                if image.size > 1000000:
                    #raise ValidationError("File too big")
                    return 0
            except:
                pass
            image = Image.open(image)
            image = MakeThumbnail(image)
            return image
        else:
            raise 0#ValidationError("File is corrupt") 

在views.py中,我有:

class UserProfileEditView(UpdateView):
    model = UserProfile
    form_class = UserProfileForm
    template_name = "edit_profile.html"

    def get_object(self, queryset=None):
        return UserProfile.objects.get_or_create(user=self.request.user)[0]

    def get_success_url(self):
        return reverse_lazy("profile", kwargs={'slug': self.request.user})

image.size为我崩溃,给出了错误:

Exception Type:     NotImplementedError 
Exception Location:     /home/hassan/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/files/storage.py in size, line 114

storage.py中的第114行仅指向附近:

def size(self, name):

    """

    Returns the total size, in bytes, of the file specified by name.

    """

    raise NotImplementedError()

settings.py 中的DEFAULT_FILE_STORAGE = storages.backends.azure_storage.AzureStorage

models.py中的UserProfile模型是:

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True)
    previous_retort = models.CharField(blank=True, max_length=500)
    avatar = models.ImageField(upload_to=upload_avatar_to_location, storage=OverwriteStorage(), null=True, blank=True )

    def __unicode__(self):
        return u"%s's profile" % self.user

之前有人遇到过这种事吗?如果您觉得它丢失了,请向我询问更多信息。

谢谢!

1 个答案:

答案 0 :(得分:0)

当我试图重现你的问题时,它似乎在我这边工作得很好。这是我的代码snippt:

forms.py

from django import forms
from PIL import Image, ImageFile

class UploadImageForm(forms.Form):
    image_file=forms.ImageField(
        label='upload an image'
    )
    def clean_avatar(self):
        image=self.cleaned_data.get("image_file")

        if image:
            print image.size
            if image.size > 1000000:
                raise ValidationError("File is too big")
            image = Image.open(image)
            #image = MakeThumbnail(image)
            return image
        else:
            raise ValidationError("File is corrupted")

view.py

def image(request):
    if request.method == 'POST':
        form = UploadImageForm(request.POST, request.FILES)
        if form.is_valid():
            form.clean_avatar()
            return HttpResponse('some pages')
    else:
        form = UploadImageForm()
    return render(
        request,
        'app/image.html',
        {'form': form},
        context_instance=RequestContext(request)
    )

由于您的要求是在放入Azure存储之前清理映像,所以我认为它应该与django存储错误相关,也许我身边有一些误解,请您提供更多代码片段来帮助我们重现你的问题。

更新

就我而言,我必须做一些类似于重现你的问题的技巧:

def clean_avatar(self):
    #this image here, is the object <InMemoryUploadedFile, len() = 23170>
    image=self.cleaned_data.get("avatar")
    #use PIL.image to open it, can parse into <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1003x366 at 0x2AA9E50>
    #i assume you leverage your custom OverwriteStorage() function and dierctly returned the PIL image object 
    image = Image.open(image)

我在VS中调试,我探索了图像对象,发现有一个fp对象包含_szieenter image description here

因此,您可以尝试使用image.fp._size代替image.size