Джанго Изменить размер изображения в формах - PullRequest
0 голосов
/ 21 ноября 2018

Я использую 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'

1 Ответ

0 голосов
/ 21 ноября 2018

Я сделал схожую вещь, но не в формах.Мой подход был такой:

# 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
...