AttributeError: объект «cStringIO.StringO» не имеет атрибута «fileno» при использовании django-imagekit

Я использую django-imagekit для загрузки изображений и столкнулся со следующей ошибкой:

AttributeError at /car/7/

'cStringIO.StringO' object has no attribute 'fileno'

Request Method:     GET 
Request URL:    http://luxingnan.azurewebsites.net/car/7/
Django Version:     1.8
Exception Type:     AttributeError
Exception Value:    

'cStringIO.StringO' object has no attribute 'fileno'

Exception Location:     D:\home\site\wwwroot\env\Lib\site-packages\pilkit\utils.py in
__enter__, line 248
Python Executable:  D:\Python27\python.exe
Python Version:     2.7.8
Python Path:    

[u'D:\\home\\site\\wwwroot\\env\\Lib\\site-packages',  '.',  'D:\\Windows\\SYSTEM32\\python27.zip',  'D:\\Python27\\DLLs',  'D:\\Python27\\lib',  'D:\\Python27\\lib\\plat-win',  'D:\\Python27\\lib\\lib-tk',  'D:\\Python27',  'D:\\Python27\\lib\\site-packages',  'D:\\home\\site\\wwwroot']

Server time:    Thu, 16 Apr 2015 12:28:26 +0000

ниже мой код:

# models.py
class Carpic(models.Model):
    picture = models.ImageField('pic',upload_to='car-pictures')
    picture_slide = ImageSpecField(source='picture',
        processors=[ResizeToFill(762, 456)],
        format='JPEG',
        options={'quality': 60}
        )
# template.html
{% for pic in pictures %}
<li><img src="{{pic.picture_slide.url}}"/></li>
{% endfor %}

Может ли кто-нибудь сказать мне, что мне делать? Спасибо


person JSNoob    schedule 16.04.2015    source источник
comment
эта ошибка связана с пакетом обработки изображений pilkit, я проследил проблему с помощью некоторых исследований и обнаружил, что проблема связана с классом FileWrapper в pilkit/utils.py, пытающимся вызвать fileno() в экземпляре StringIO, этот ответ SO обеспечивает подробное объяснение stackoverflow.com/a/5903627/4724196   -  person HassenPy    schedule 16.04.2015
comment
попробуйте открыть задачу в репозитории pilkit здесь github.com/matthewwithanm/pilkit/issues   -  person HassenPy    schedule 16.04.2015
comment
что странно, так это то, что все в порядке в локальной среде. Но после того, как я развернул его в Azure, он выдает мне эту ошибку   -  person JSNoob    schedule 16.04.2015
comment
вы разрабатываете в среде Linux или в Windows?   -  person HassenPy    schedule 17.04.2015
comment
@HassenPy Спасибо, Хассен. Вместо этого я попробовал Heroku, и сейчас все работает хорошо. Я думаю, это, вероятно, проблема Azure   -  person JSNoob    schedule 17.04.2015
comment
@HaseeenPy Я не понимаю, почему проблема в FileWrapper, он просто действует как прокси. Проблема в том, что базовый файл (StringIO) не имеет fileno() и что-то хочет его. Первым шагом к решению этой проблемы было бы выяснить, что вызывает fileno()   -  person matthewwithanm    schedule 20.04.2015


Ответы (1)


Только что получил возможность взглянуть на это (и вашу проблему GH). Я включу свой ответ здесь, потому что это кажется правильным поступать ТАК (:

Так что похоже, что это особенность Azure, но мы определенно можем исправить ее в PILKit.

В PILKit есть утилита для отключения некоторых PIL. шум. Это делается путем временной замены stderr (используя его файловый дескриптор). По-видимому, в Azure stderr — это экземпляр StringIO (у которого нет файлового дескриптора). Нам просто нужно добавить защиту в утилиту для этого случая (так же, как для когда dev/null недоступен для записи). Это небольшое изменение, но я очень занят в данный момент. PR приветствуется!

Таким образом, другими словами, это не проблема с FileWrapper (как предлагается в комментариях), а скорее комбинация поддельного stderr Azure и утилиты quiet PILKit.

person matthewwithanm    schedule 20.04.2015
comment
Это кажется странным способом добиться этого. Насколько я понимаю, переназначение sys.stderr — это обычный метод временного перенаправления stderr, и это должно отлично работать со StringIO и т. д. - person Kevin; 20.04.2015
comment
Переназначение sys.stderr Python не делает того же самого. Шумность PIL на самом деле происходит на более низком уровне. Ознакомьтесь с этим вопросом SQ для лучшего описания проблемы. мы там решаем. - person matthewwithanm; 21.04.2015
comment
Хм... В таком случае настоящий stderr все равно должен указывать на что-то. В большинстве систем stderr — это fd #2. Возможно, вы сможете жестко запрограммировать это, если оно достаточно надежно. Я также считаю, что есть макрос C, который расширяется до stderr fd для большей переносимости. Я предполагаю, что он может быть закрыт, но в этом случае его сохранение должно быть тривиальным. - person Kevin; 21.04.2015
comment
Я думаю, что чувствую себя более комфортно, просто пытаясь получить fd и отказываясь от него, если есть ошибка, чем делать предположения об дескрипторе. Но если вы твердо настроены по этому поводу, мы можем обсудить это более подробно на GH. - person matthewwithanm; 21.04.2015