尝试使用 Azure 存储在 Django 中获取 image.size 时出现 NotImplementedError
NotImplementedError when trying to get image.size in Django with Azure Storage
在 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()
还有 DEFAULT_FILE_STORAGE = storages.backends.azure_storage.AzureStorage
在 settings.py.
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
有人遇到过这种事情吗?如果您觉得缺少它,请向我询问更多信息。
谢谢!
当我试图重现您的问题时,但它似乎在我这边运行良好。这是我的代码片段:
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
对象,其中包含 _szie
:
所以你可以尝试使用image.fp._size
而不是image.size
在 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()
还有 DEFAULT_FILE_STORAGE = storages.backends.azure_storage.AzureStorage
在 settings.py.
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
有人遇到过这种事情吗?如果您觉得缺少它,请向我询问更多信息。
谢谢!
当我试图重现您的问题时,但它似乎在我这边运行良好。这是我的代码片段:
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
对象,其中包含 _szie
:
所以你可以尝试使用image.fp._size
而不是image.size