我正在使用python 3.6和Django 2.0。
我有一张要上传到模型的正方形图像。我目前在模型中有一个图片字段,可以上传。
avatar = models.ImageField(path_and_rename, max_length=255, blank=True
我想将上传的任何正方形图像的大小调整为750到750。我想到了一种实现方法,但是我不认为我将其保存为正确的类型,因为它给我一个错误。
'Image' object has no attribute '_committed'
如何调整方形图像的尺寸以满足我需要的新尺寸。
我的代码(省去了验证使其更简单):
forms.py
def clean_avatar(self):
avatar = self.cleaned_data['avatar']
try:
print(len(avatar))
w, h = get_image_dimensions(avatar)
max_width = max_height = 750
image = Image.open(avatar)
resized_image = image.resize((max_width,max_height), Image.ANTIALIAS)
print(type(avatar))
print(type(image))
print(type(resized_image))
return resized_image
except
...
上面的输出是
<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
<class 'PIL.JpegImagePlugin.JpegImageFile'>
<class 'PIL.Image.Image'>
如果我返回avatar
,它会起作用,但是当我返回resized_image
时,它将不起作用。如何使resized_image
的数据类型为avatar
?
完整错误消息:
File "C:\myapp\lib\site-packages\django\core\handlers\exception.py" in inner
35. response = get_response(request)
File "C:\myapp\lib\site-packages\django\core\handlers\base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "C:\myapp\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\myapp\lib\site-packages\django\views\generic\base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "C:\myapp\lib\site-packages\django\contrib\auth\mixins.py" in dispatch
52. return super().dispatch(request, *args, **kwargs)
File "C:\myapp\lib\site-packages\django\views\generic\base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "C:\myapp\lib\site-packages\django\views\generic\edit.py" in post
194. return super().post(request, *args, **kwargs)
File "C:\myapp\lib\site-packages\django\views\generic\edit.py" in post
142. return self.form_valid(form)
File "C:\myapp\lib\site-packages\django\views\generic\edit.py" in form_valid
125. self.object = form.save()
File "C:\myapp\lib\site-packages\django\forms\models.py" in save
456. self.instance.save()
File "C:\myapp\lib\site-packages\django\contrib\auth\base_user.py" in save
73. super().save(*args, **kwargs)
File "C:\myapp\lib\site-packages\django\db\models\base.py" in save
729. force_update=force_update, update_fields=update_fields)
File "C:\myapp\lib\site-packages\django\db\models\base.py" in save_base
759. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\myapp\lib\site-packages\django\db\models\base.py" in _save_table
820. for f in non_pks]
File "C:\myapp\lib\site-packages\django\db\models\base.py" in <listcomp>
820. for f in non_pks]
File "C:\myapp\lib\site-packages\django\db\models\fields\files.py" in pre_save
285. if file and not file._committed:
Exception Type: AttributeError at /account/details/
Exception Value: 'Image' object has no attribute '_committed'
答案 0 :(得分:0)
我做了类似的事情,但是没有形式。我的方法是这样的:
# override Model Save Method
class YourModel(models.Model):
...
def save(self, **kwargs):
resize = kwargs.pop('resize', False)
instance = super(YourModel, self).save(**kwargs)
if resize:
pil_image = Image.open(self.avatar.path)
# resize related code
resized_image = pil_image.resize((max_width,max_height), Image.ANTIALIAS)
resized_image.save(self.avatar.path)
return instance
并从如下形式调用此保存方法:
class YourForm(...):
...
def save(self, commit=True):
instance = super(YourForm, self).save(commit=False)
instance.save(resize=True) # call model save method from here
return instance
也许您可以这样尝试:
import io
# clean method
w, h = get_image_dimensions(avatar)
max_width = max_height = 750
image = Image.open(avatar)
resized_image = image.resize((max_width,max_height), Image.ANTIALIAS)
img_in_memory = io.BytesIO()
resized_image.save(img_in_memory, format="png")
return img_in_memory