Уведомления

Группа в Telegram: @pythonsu

#1 Июль 10, 2009 23:16:13

m3ou
От:
Зарегистрирован: 2009-07-10
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

InMemoryUploadedFile -> File

Проблема заключается в следующем. Есть картинки, которые нужно ресайзить на лету, а затем сохранять(для последующего preview)
Искал аналогичные проблемы в гугле. Нашёл 2 варианта решения. Но 1 меня не устраивает, т.к. файл сохраняется 2 раза, затем переоткрывается и т.п.
http://spindrop.us/2009/02/21/resizing-image-on-upload-in-django/
Здесь - общая идея - обработать с помощью PIL StringIO обьект, затем сохранить его, затем открыть open, и передать FIle(opened-descriptor)

2-я - Попросту не работает, но идея красива. То же самое, но сохраняем в StringIO обьект, затем на его основании делаем InMemoryUploadedFile.
http://softwaremaniacs.org/forum/django/10881/

и в первой и во второй версии всё делается в _clean методах соответствующих полей.

Вся штука в том, что затем сей обьект, который был получен в _clean-е должен затем использоваться в save формы в виде
table_name.photo.save(string_filename, File_object)
А у нас - InMemoryUploadedFile…..
Расковырял по сорцам и с помощью WingIDE. Пока сделал следующий “костыль” на основании того, что в File(file) есть file.mode, а в InMemoryUploadedFile - его лишь нету…
Сделал класс

class InMemoryUploadedFileWrite(InMemoryUploadedFile):
mode = "w"
А затем использую его
_clean(поля):
memfile = InMemoryUploadedFileWrite(magic, image.field_name, filename, image.content_type, magic.len, image.charset)
upl = File(memfile)
return {'filename': filename, 'content': upl}
_save(формы):
table_name.photo.save(filename, upl)
Всё работает и ресайзит. Но это костыль.

Вопрос. Может кто делал уже? Да ведь задача-то тривиальная - просто отресайзить(можно и без ресайза) и сохранить картинку зааплоаденную…..
Зааплоаденная картинка(из формы) является
    def __clean_upload_img(self, name):
image = self.cleaned_data[name]
всё та же InMemoryUploadedFile.
Но чтоб её потом сохранить в форме - надо сохранять обьект File. Т.е. с этим сталкивался очень много кто….

На форуме искал - готовых ответов - нет.

Спасибо



Офлайн

#2 Июль 13, 2009 21:29:36

slav0nic
Команда
От: dp.ua
Зарегистрирован: 2006-05-07
Сообщения: 2260
Репутация: +  41  -
Профиль   Отправить e-mail  

InMemoryUploadedFile -> File

Офлайн

#3 Июль 14, 2009 09:41:41

m3ou
От:
Зарегистрирован: 2009-07-10
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

InMemoryUploadedFile -> File

slav0nic
http://stackoverflow.com/questions/505868/django-how-do-you-turn-an-inmemoryuploadedfile-into-an-imagefield/506031#506031 это смотрел? я обычно примерно так и делаю

вот вроде то что надо http://snipt.net/danfreak/generate-thumbnails-in-django-with-pil
Спасибо огромное. Я сделал не совсем так, как описано там, ибо у меня форма не статическая, а динамическая, да ещё и ажаксовская.
Вот код. Может кому-то поможет.
Вся фишка была в SimpleUploadedFile. Его конструктор возвращает подходящий по совместимости обьект.

class InputForm(SkeletForm):

………………..

def __clean_upload_img(self, name):
image = self.cleaned_data
if not image:
return image
if image == '':
self.cleaned_data = None
return self.cleaned_data

if image.size > settings.FILE_UPLOAD_MAX_MEMORY_SIZE:
raise forms.ValidationError('Image size more than %i Mb.' % \
(settings.FILE_UPLOAD_MAX_MEMORY_SIZE / (1024*1024)))

content = StringIO(image.read())
img = imageResize(content, (800, 600))
magic = StringIO()
img.save(magic, ‘JPEG’, quality=100)

filename = hashlib.md5(magic.getvalue()).hexdigest()+'.jpg'#TODO make it unique!!!
magic.seek(0)
upl = SimpleUploadedFile(filename, magic.read(), content_type='image/jpeg')

return {'filename': filename, ‘content’: upl}

def clean_out_ph1(self):
return self.__clean_upload_img('out_ph1')
……………………
def save(self):
………….
l_building.out_ph1.save(self.cleaned_data, self.cleaned_data)
……


А все настройки(пути для сохранения и т.п.) - описаны в модели.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version