Загрузка файлов из форм в TurboGears
Макс ИщенкоОпубликовано 19.03.2006 в Статьи
Иван Сагалаев рассказал как обстоят дело с загрузкой файлов через веб-формы в Django. Я решил посмотреть какая ситуация у TurboGears.
В целом все ОК, если бы не один момент. TurboGears использует FormEncode для валидации форм. FormEncode содержит FieldStorageUploadConverter для обработки полей типа FILE, вот только оно не работает.
Похоже, что это просто баг - надо бы зафайлить отчет об ошибке разработчикам.
В итоге мне пришлось написать свой валидатор. Другое отличие - TurboGears не имеет специальной логики для хранения картинок/файлов. Для простоты я решил сохранить обложку в БД. Для полноты картины прилагаю и весь остальной код, готовый TG-проект можно взять здесь.
Детально комментировать мне лень, но если будет интерес можно будет написать несколько более детальных постов о TurboGears.
Так форма описывается:
class FileUploadConverter(validators.FancyValidator):
def to_python(self, value, state=None):
if isinstance(value, cgi.FieldStorage):
if value.filename:
return value
raise validators.Invalid('invalid', value, state)
else:
return value
album_form = widgets.TableForm(name='album',
fields=[
widgets.TextField('title', validator=validators.UnicodeString()),
widgets.FileField('cover', validator=FileUploadConverter(not_empty=False))
])
А так - отображается (плюс показываются существующие записи):
@turbogears.expose(template='tff.templates.welcome')
def index(self):
albums = Album.select()
return dict(albums=albums, form=album_form)
Это представление (Kid шаблон):
<h2>Existing albums</h2>
<p py:for="album in albums">
<img title=${album.title} alt=${album.title}<br />
py:if="album.cover" src="/get_cover?id=${album.id}" />
<span py:if="not album.cover" py:strip="True">${album.title} (no cover)</SPAN>
</p>
<h2>Add new album</h2>
${form.display(action='do_add_album')}
Так происходит валидация и добавление нового альбома:
@turbogears.error_handler(index)
@turbogears.validate(form=album_form)
@turbogears.expose()
def do_add_album(self, title=None, cover=None):
if cover is not None:
cover = cover.value
# cover.filename contains original filename and cover.type - content-type
a = Album(title=title, cover=cover)
turbogears.flash('Album has been added')
turbogears.redirect('/')
Ну а это - вспомогательный метод для отображения картинки на лету:
@turbogears.expose()
@turbogears.validate(validators={'id':validators.Int()})
def get_cover(self, tg_errors=None, id=None):
if not tg_errors:
try:
album = Album.get(id)
content_type = 'image/gif'
cherrypy.response.headers['Content-Type'] = content_type
return album.cover
except sqlobject.SQLObjectNotFound:
pass
return ''
Это собственно модель:
class Album(SQLObject):
title = UnicodeCol(length=90)
cover = BLOBCol()
Понравилась статья? Подпишись на обновления по RSS/E-mail

Если не сложно, поставьте в CSS на класс для кода, размер шрифта по-больше.
Очень неудобно читать исходники с микро-шрифтом.
Вот мой скриншот
Так лучше?
А по-хорошему, надо быть сделать раскраску синтаксиса, хотя бы для Python. Может кто что посоветовать?
Мені подобається як на rsdn.ru зроблено. Можеш подивитися як там зроблено, там до речі, якщо не помиляюся код для форматера єдиний для сайту та для Януса(офлайн-клієнт форумів)тому там можна підглянути, що і як, правда .NET.
Да. Так гораздо лучше. Спасибо! =)
Подсветка питоновского кода, написанная на самом питоне:
http://www.peck.org.uk/p/python/py2html.html
Вряд-ли подойдёт…
Можно попробовать сделать как, например, здесь:
линк съелся
повторю:
http://www.turbogears.org/preview/docs/tutorials/wiki20/page2.html