В последнем проекте на Django я реализовывал модное нынче на вебе тегирование. Нужно было, чтобы пользователи могли навешивать на всякие объекты теги, причем не только выбирая их из заданного списка, но и при желании вводя свои. Получился довольно приятный интерфейс с автоподсказкой на javascript'е, а поскольку навешивать теги приходилось на самые разные объекты в системе, он еще и вышел довольно универсальным.

Достаточно универсальным для того, чтобы превратить его в подключаемую библиотечку, что я и сделал.

Получилась TagsField — библиотечка, которую можно легко использовать в любом проекте на Django, а при желании смотреть в код, и не только на нем :-). Как пользоваться, описано на вышеприведенной странице: знакомьтесь, скачивайте, пользуйтесь.

Немножко о том, как это работает.

Структурно теги — это отдельная модель, с которой другие модели связаны через ManyToManyField. Единственная проблема с ManyToMany — это то, что для него автоматическими манипуляторами создается <select multiple>, у которого есть два не устроивших меня ограничения:

В итоге я сделал наследника от ManyToManyField, который все это исправляет. Для того, чтобы можно было добавлять новые значения, вместо цифровых IDшек из формы передаются сами строковые значения. Поле ищет для каждого существующую запись, и если не находит, тут же ее создает.

Поиск этот достаточно интеллектуальный: не только игнорирует регистр букв, но и знаки препинания, пробелы, разницу между "е" и "ё", а также напрочь не замечает слово "the".

У последнего правила ноги растут из специфики сервиса, в котором это было написано: музыкальные коллекции. Многие люди записывают названия альбомов и исполнителей в виде "Doors, The", чтобы они сортировались по алфавиту по наиболее значимой букве в названии, а не по "T". Игнорирование этого слова позволяет считать "The Doors" и "Doors, The" одинаковыми названиями.

В итоге, то, что это поле несильно отличается от стандартного и использует стандартные механизмы для формирования контрола для формы, это поле автоматически работает во всех стандартных манипуляторах, generic views, а также в админке Django (для чего, правда, придется преписать скрипты и стили в директорию админки).

Еще одна маленькая особенность текущей версии в том, что для автоподсказки тегов не используется Ajax. Я предположил, что даже если тегов будет штук 100-200 (что, вообще-то, и так уже слишком много для их осмысленного применения), это достаточно мало, и их можно грузить в страницу прямо сразу, без дополнительной подгрузки. Но вот сам javascript'овый код подсказки, который был написан не только для тегов, но и для альбомов и исполнителей, работать с Ajax'ом умеет. Поэтому если у кого-то возникнет такая нужда, напишите, опишу что там где включить и подправить.

Комментарии: 12

  1. DenD

    На редкость удобный интерфейс тегирования вышел.
    Как только увидел картинку - подумал, неплохо бы, если бы так было в реале. Перешел на демку - так и есть :) Просто, удобно, логично и функционально.
    Браво, Иван!

  2. Vitaalyy

    В ИЕ6 ужасно выглядит. Все мигает, какие-то полосы остаются, впечатление совершенно недоделанной вещи. Уж лучше яхушные контролы использовать, они хоть монструозные, но не такие глюченые.

  3. Иван Сагалаев

    Спасибо, погляжу. Надо сказать, что в IE он вообще не тестировался :-).

    Однако основная ценность TagsField не в клиентской части, а в интеграции с Django. Javascript'овую часть можно, в общем-то, и другую прицепить.

  4. Иван Сагалаев

    Вроде бы все поправил в IE. Заодно немного поменял поведение:

    • раньше у выбора мышкой и клавиатурой было два разных курсора (не знаю, почему мне это казалось логичным :-)), теперь один
    • по клавише ENTER добавляются новые поля тегов
  5. vitaly

    вот теперь другое дело :)

  6. Julik

    Правило про the и стоп-слова хорошее, я когда делал адресную книгу стал даже писать в базу специальное поле для сортировки без артикля

  7. pepelsbey

    Я вот долго не мог понять почему iPod в списке исполнителей ставит The Doors сразу после Cranberries. Чудеса юзабилити...

    Кстати, есть группа "The The"... интересно, что будет с ней?

  8. Иван Сагалаев

    Группа "The The" превратится в "the the". И будет на "T", соответственно. Хотя возможно, что в той версии, которая лежит на сайте, еще осталась ошибка, которая этому мешала. Но в ближайшее время все будет хорошо :-).

  9. buriy

    А как несколько раз использовать эти теги?
    Т.е. чтобы 2 таблицы с тегами были. Например, одна называлась Tags1, а вторая Tags2.

  10. Kirill Morozov

    Удерживайте "Control" (или "Command" на Mac) для выбора нескольких.

    Не знаю как на тигре, но вот на леопарде в 3 сафари это не работает, всегда только один тег какой-то выбирается.
    Типа багрепорт :) Тестировал только в админке джанговской.

  11. Andrew Kornilov

    Извените за нубский вопрос. Я только начинаю разбираться с джанго. Возможно ли для єтой библиотеки реальизовать:
    1. Перегрузку отображения фильтра списка в админке в виде облака тегов (не обязательно взвешенного - только бы не html-списком)
    2. В админке в списке для каждой записи отображать теги.

    Стоит ли заморачиваться с реализаціей всего этого?

  12. Иван Сагалаев

    Я бы не стал :-). Мне кажется, вы хотите сделать одну из типичных ошибок начинающего джангиста: считаете админку полноценным пользовательским интерфейсом. Это не так. Это простой и тупой шорткат, позволяющий не тратить уйму времени на нудную работу. Но вот кастомизовать его, чтобы он был специфически удобным под какую-то задачу обыно сложнее, чем написать собственные интерфейсы.

Добавить комментарий