【问题标题】:NotImplementedError when trying to get image.size in Django with Azure Storage尝试使用 Azure 存储在 Django 中获取 image.size 时出现 NotImplementedError
【发布时间】:2016-05-09 09:23:37
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

  • settings.py中DEFAULT_FILE_STORAGE的值是多少?
  • storages.backends.azure_storage.AzureStorage
  • AzureStorage 未实现 image.size。这可能是因为您只有对 azure 服务器的间接读/写访问权限,因此获取文件大小比在本地文件系统上要昂贵得多。
  • 您可以建议任何解决方法吗?

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


【解决方案1】:

当我试图重现您的问题时,但它似乎对我来说工作正常。这是我的代码片段:

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 Storage之前清理图像,所以我认为它应该是相对于django存储handers,也许我这边有一些误解,请您提供更多代码sn-ps来帮助我们重现您的问题。

更新

在我这边,我必须做一些类似技巧来重现您的问题:

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对象包含_szie:

所以你可以尝试使用image.fp._size 而不是image.size

【讨论】:

  • 嘿 Gary,我根据您的建议在原始问题中添加了更多代码。希望这能帮助您隔离问题?
  • 你能提供你的UserProfile吗?就我而言,很难猜出你的对象。因为没有UserProfile,它在我这边也能正常工作。
  • 加里也加了。
  • 我想我已经以类似技巧的方式重现了这个问题,无论如何,您可以参考我的答案中的更新。如果有任何进一步的问题,请随时告诉我。
  • 所以当图像被“重新提交”时会出现这个错误。如果我提交新图片,例如sandra-3.png,image.size 工作正常。但是,如果我重新提交包含该图像的表单,则会收到错误消息(此时图像已变为 avatars/9fc3a7ff-f95f-47e6-aa20-720be748beb0.jpg),其中 avatars 是我的 Azure blob 中的一个文件夹。
猜你喜欢
  • 2015-08-20
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 2017-07-26
  • 2017-07-01
相关资源
最近更新 更多