Интенсив «Шаблоны и анти-шаблоны дизайна». Загрузка прямо в мозг разработчика.

Загрузка файлов из форм в TurboGears

Иван Сагалаев рассказал как обстоят дело с загрузкой файлов через веб-формы в 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>
  <img alt="${album.title}<br" title="${album.title}">
    py:if="album.cover" src="/get_cover?id=${<a href="http://album.id" target="_blank">album.id</a>}" />
  <span>${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':<a href="http://validators.Int" target="_blank">validators.Int</a>()})
    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()
  • Популярное

7 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Можно попробовать сделать как, например, здесь:

Подсветка питоновского кода, написанная на самом питоне: http://www.peck.org.uk/p/pytho...Вряд-ли подойдёт...

Да. Так гораздо лучше. Спасибо! =)

Мені подобається як на rsdn.ru зроблено. Можеш подивитися як там зроблено, там до речі, якщо не помиляюся код для форматера єдиний для сайту та для Януса (офлайн-клієнт форумів) тому там можна підглянути, що і як, правда.NET.

Так лучше? А по-хорошему, надо быть сделать раскраску синтаксиса, хотя бы для Python. Может кто что посоветовать?

Если не сложно, поставьте в CSS на класс для кода, размер шрифта по-больше.Очень неудобно читать исходники с микро-шрифтом.Вот мой скриншот

Подписаться на комментарии