Ошибка ввода-вывода при закрытом файле в Django При создании эскиза загруженного изображения - PullRequest
0 голосов
/ 19 февраля 2019

Я создаю сайт django, и когда я загружаю изображение (модель «Фото») через представление администратора, я хочу создать произвольный эскиз и сохранить его в поле миниатюр изображений.Миниатюры генерируются хорошо, но когда модель Photo пытается сохранить, я получаю, что я пытался выполнить операцию ввода-вывода для закрытого объекта: «Операция ввода-вывода для закрытого файла».Трассировка стека отслеживает обратный вызов до суперкласса, поэтому я думаю, что это сделано с помощью функции generate_thumbnail.

Что я делаю не так?Любая помощь будет оценена.

from PIL import Image
from io import BytesIO
from django.core.files.base import ContentFile

class Photo(models.Model):
photo=models.ImageField(upload_to='photos/',blank=True)
thumbnail = models.ImageField(upload_to='thumbs/', editable=False, null=True)
def save(self,*args,**kwargs):    
    if self.photo:
       self.generate_thumbnail()
    super(Photo, self).save(*args,**kwargs)

def generate_thumbnail(self):
    img =Image.open(self.photo)
    img.thumbnail([consts.THUMB_HEIGHT,consts.THUMB_WIDTH],Image.ANTIALIAS)
    name = os.path.basename(self.photo.name)
    thumb_name, thumb_ext = os.path.splitext(name)
    thumb_ext=thumb_ext.lower()
    outname="thumb_"+thumb_name+thumb_ext
    if thumb_ext in ['.jpg','.jpeg']:
        filetype='JPEG'
    elif thumb_ext == '.gif':
        filetype='GIF'
    elif thumb_ext=='.png':
        filetype = 'PNG'
    else:
        raise Exception("Failed to generate thumbnail. Is the filetype valid?")
    temp_thumb=BytesIO()
    img.save(temp_thumb,filetype)
    temp_thumb.seek(0)
    self.thumbnail.save(outname,ContentFile(temp_thumb.read()),save=False)  
    temp_thumb.close()
    return True

Итак, через день, тот же код, другая ошибка.Теперь этот файл не найден с файлом во временном каталоге.Трассировка стека для этой ошибки выглядит следующим образом.

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/coffins/photo/11/change/

Django Version: 2.1.5
Python Version: 3.7.2
Installed Applications:
['storages',
 'coffins.apps.CoffinsConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/blah/venv/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/blah/venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/blah/venv/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/contrib/admin/options.py" in wrapper
  604.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/contrib/admin/sites.py" in inner
  223.             return view(request, *args, **kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/contrib/admin/options.py" in change_view
  1640.         return self.changeform_view(request, object_id, form_url, extra_context)

File "/blah/venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/contrib/admin/options.py" in changeform_view
  1525.             return self._changeform_view(request, object_id, form_url, extra_context)

File "/blah/venv/lib/python3.7/site-packages/django/contrib/admin/options.py" in _changeform_view
  1564.                 self.save_model(request, new_object, form, not add)

File "/blah/venv/lib/python3.7/site-packages/django/contrib/admin/options.py" in save_model
  1091.         obj.save()

File "/blah/coffins/models.py" in save
  62.         super(Photo, self).save(*args,**kwargs)

File "/blah/venv/lib/python3.7/site-packages/django/db/models/base.py" in save
  718.                        force_update=force_update, update_fields=update_fields)

File "/blah/venv/lib/python3.7/site-packages/django/db/models/base.py" in save_base
  748.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/blah/venv/lib/python3.7/site-packages/django/db/models/base.py" in _save_table
  809.                       for f in non_pks]

File "/blah/venv/lib/python3.7/site-packages/django/db/models/base.py" in <listcomp>
  809.                       for f in non_pks]

File "/blah/venv/lib/python3.7/site-packages/django/db/models/fields/files.py" in pre_save
  288.             file.save(file.name, file.file, save=False)

File "/blah/venv/lib/python3.7/site-packages/django/db/models/fields/files.py" in save
  87.         self.name = self.storage.save(name, content, max_length=self.field.max_length)

File "/blah/venv/lib/python3.7/site-packages/django/core/files/storage.py" in save
  49.         return self._save(name, content)

File "/blah/venv/lib/python3.7/site-packages/django/core/files/storage.py" in _save
  255.                     file_move_safe(content.temporary_file_path(), full_path)

File "/blah/venv/lib/python3.7/site-packages/django/core/files/move.py" in file_move_safe
  56.     with open(old_file_name, 'rb') as old_file:

Exception Type: FileNotFoundError at /admin/coffins/photo/11/change/
Exception Value: [Errno 2] No such file or directory: '/var/folders/s6/w4dbxvkj0ng4l7s5_pqd_mxr0000gn/T/tmpunp8vg4b.upload.jpg'

1 Ответ

0 голосов
/ 26 февраля 2019

Мое решение для этого было в конечном итоге загрузить библиотеку, которая сделала это: stdimage делает именно то, что я хотел, чтобы он делал - он создает миниатюру определенного кодером размера во время загрузки изображения и сохраняет его в любом приложении.Память есть - в моем случае S3.Кажется, что большинство библиотек создают миниатюру по требованию, и миниатюра указывается в шаблоне, а не в модели.Как правило, это требовало некоторого memcaching.Для моих нужд это не было оптимальным.Посмотрев на код для этого плагина, они охватывают множество крайних случаев, с которыми я не имел здесь дело, и не захотели бы уделить время, чтобы покрыть это самостоятельно.

Спасибо всем, кто помог!

...