This version of the page http://piranha.org.ua/blog/tag/news/ (0.0.0.0) stored by archive.org.ua. It represents a snapshot of the page as of 2008-06-20. The original page over time could change.
Amazon byteflow: Posts
About Blog Dev | Alfa Romeo SZ Conkeror wishlist

All articles, tagged with “news”

Граф чейнджсетов в Меркуриале

В транке меркуриала появилась одна очень клёвая штука — дерево чейнджсетов в hgweb’е. Раньше его можно было посмотреть только локально, а сейчас — и онлайн. Например, вот byteflow.

Кстати, последние изменения в crew1 говорят о том, что возможно в скором времени можно будет коммитить без рабочей копии (т.е. прямо из памяти, используя API). :-)

1

Репозиторий, в котором проходит основная разработка — его потом мержат в транк.

QS-RF

Сегодня про это пишут все, но я всё равно не могу промолчать. :-)

Ветку разработки queryset-refactoring смержили в транк Django, что означает приход порядочной толпы приятностей. ;-) Мне лично очень нравится возможность посмотреть SQL до выполнения собственно запроса (QuerySet.query.as_sql()), ну и логично работающую фильтрацию по одной и той же таблице, хорошо описанную Иваном. Ну и ещё долгожданное многими наследование моделей.

Отличные новости, в общем! :-)

Обновления

Буквально только-только реализовал в Byteflow одну маленькую (совсем), но очень полезную штуку, подсказанную Катапом: в стандарте Atom’а есть два разных поля, использующихся для указания даты для элемента — published и updated, при этом updated - обязательное.

Раньше в updated просто кидалась дата создания поста или комментария, но сейчас всё по-другому. :) Теперь дата создания поста (которую можно изменить в админке для приведения в более адекватный вид, для создания “поста в будущем”) или комментария идёт в published, а в updated попадает дата, изменяющаяся при каждом изменении объекта. По идее, это должно заставить обновлённый объект появляться во всей своей красоте в рсс-ридерах. :-)

Enjoy! :)

OpenID server

Этот пост будет кратким — благодаря стараниям Олега в Byteflow теперь присутствует сервер OpenID. Клёво. :-)

P.S.А ещё byteflow — второй по тегу django на ohloh.net, после самой джанги. :-)

OpenID refactoring

Хорошие новости - я порядочно переделал механизм работы с опенидом в блоге. Правда, сами внутренности openidconsumer почти не подверглись издевательствам, изменения прошли в основном в коде работы с пользователем. Но зато для пользователей поменялось всё порядочно.

Во-первых, теперь после попытки логина с неизвестным блогу OpenID’ом теперь не покажет две непонятные формы “введите логин/пароль”, а молча залогинит - создав по пути нового пользователя. Правда, может выкинуть на старую страничку - если вдруг система sreg отдаст email, уже существующий в базе (если она не отдаст email, то всё пойдёт по первому сценарию без привлечения пользователя к процессу).

Во-вторых, теперь в профиле есть ссылочка на список ассоциированных с пользователем OpenID’ов, где их можно удалять и добавлять новые.

Так что жизнь становится легче и удобнее с каждым часом. :D Велкам! ;-)

Темы

С подачи lorien‘а блог обзавёлся возможностью переопределять только нужные темплейты в темах. Всего лишь добавил загрузчик темплейтов (это оказалось очень просто), да настройку THEME - теперь первым делом темплейты ищутся в themes/{{ THEME }}/, а уж потом в templates/. :-) Ещё думаю сделать добавление стилей в зависимости от этой настройки, но не решил каким образом будет лучше. Наверное, темплейт тег, который будет проверять существование файликов со стилями кастомных и добавлять их в хидер. Или есть варианты лучше?

Ещё подумываю добавить мультиязычность. ;-) Но как это реализовать?… Пока знаю только django-multilingual и i18ndynamic. Может кто знает лучший вариант? Было бы неплохо, чтоб комментарии к разным языкам не пересекались, наверное… Или плохо? :\

Переезд

Вчера вечером заимпортировал все более-менее значимые посты из старого вордпрессовкого блога, осталось решить непонятную траблу с flatpages (сейчас почему-то работает только about :( ), и переезд можно будет считать окончательно завершённым - поставлю со старого блога редирект на этот, по возможности чтоб не промазывать по постам.

Сноски и обновление пингбека

Как я и писал, я решил добавить поддержку сносок. Оказалось это совсем просто, потому что порт Markdown на Python уже имеет такой плагин. Потому все изменения свелись к тому, что кинул mdx_markdown.py в каталог проекта и немножко переписал свою функцию text_to_html. Правда, пришлось немного поправить код самого плагина, чтобы сноски выводились так, как хочется мне, а не как придумал себе автор. :) Должен сказать, что генерация DOM в питоновском коде - то ещё уродство, лучше уж какие-то простенькие темплейты, что ли… :\

Вторая и главная новость состоит в том, что я добавил модель PingbackClient, которая запоминает те адреса, которые уже пинговались, и просто не даёт их пинговать при редактировании поста - чтоб не ждать каждый раз, пока оно пройдёт все урлы. Кроме того, это же позволит следить за тем, куда же таки дошли пинги. :) А ещё я закинул всю реализацию как отдельный проект на Google Code. :)

P.S.Кстати, замечания и дополнения привествуются. :) А то чувствую, ещё пару раз гляну на ping, и перепишу её. Уж больно ужасно вышло. :-)

Комментарии

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

Сначала я, в лучших традициях чукотской наивности, просто попытался добавить вызов функции залогинивания после подтверждения правильности комментария и чистоты помыслов его автора, но не тут-то было! Джанга мне быстренько рассказала, кто здесь хозяин и где собственно у пользователя свойство backend?

Я понял, что двумя пальцами и асфальтом не обойдусь и пошёл читать доку. После беглого просмотра жалкой пары абзацев по предыдущей ссылке я уловил, что мне надо в любом случае применить функцию authenticate, которая и установит пользователю искомое свойство. В надежде, что я обойдусь без написания своего бекенда, решил порыться в гугле - и мои опасения, в который раз, оказались обоснованными. :-) Существует тикет, как раз по моему вопросу, закрытый больше года назад Малькольмом Трединником с объяснением: “нечего голову морочить, читайте доки и пишите бекенды, это несложно”.

На самом деле всё оказалось не просто несложно, а вообще просто бесплатно. ;-) Написание первоначальной версии бекенда (только для подтверждения комментариев) заняло у меня порядка 5 минут с ловлей блох, а доработка до более модной версии, которая теперь работает и для активации пользователя (активировался - и уже залогинен :-) заняла ещё порядка 10 минут с обдумыванием, а как же будет лучше это реализовать.

Получился небольшой кусочек кода, который к тому же ещё обладает способностью к лёгкому расширению. :-) На самом деле бекенд - это просто небольшой класс, который должен иметь два метода - authenticate, для проверки валидности пришедших мандатов1, и get_user, для получения юзера и добавления его к объекту запроса (т.е. к request).

get_user, использующийся с джанговской стандартной модельюUser (а я в блоге только ей и пользуюсь), всегда выходит одинаковый (про это немного написано в последнем абзаце), потому говорить тут не о чем. А вот authenticate получился достаточно интересным, на мой взгляд: он вызывает динамически (хе-хе, использование getattr даёт право написать это слово) необходимый метод для совершения действа (например, активирования пользователя) - почему я и написал про лёгкую расширяемость.

А теперь два слова про однообразный get_user. На самом деле, когда я писал сам бекенд, я понял только, зачем нужен authenticate, и чтоб разобраться с get_user (не хотелось опубликовывать куцый пост ;-), мне пришлось рыться в джанговском contrib.auth. Внимательное чтение легко объяснило, что к чему, но я заметил очень неприятную штуку - кучу жёстко закодированных вещей. Собственно, у меня самого такое встречается (и мне откровенно неудобно такое отсылать в репозиторий, но время часто не резиновое, и общее красивое решение некогда делать), но тут… В общем, у меня роятся мысли это поправить всё, вроде не выглядит сложным. Надеюсь, соберусь это сделать (и для диплома полезно будет ;-).

1 -

не могу подобрать русского перевода для слова “credentials” - Лингво из адекватных предлагает только “мандаты”, но меня и оно как-то не устраивает. В общем, сочетания логин и пароль, или openid, или, в данном случае, активационного ключа.

Связанные объекты

Сегодня наконец-то отбросил свою лень в сторону и сделал то, о чём так долго твердили большевики! :)

Перед всем этим текстом хочу сказать спасибо Диме Догадайло, который собственно всё это и сделал. Недавно он мне говорил, что хочет этот код выложить в опенсорс, но так как этого пока не произошло - я значит буду первый, благо он мне разрешил код использовать в блоге. :-)

В Джанге, как известно, встроен свой механизм аутентификации, который часто бывает довольно удобен (самое большое удобство заключается именно в его встроенности - интеграции со всем джанговским хозяйством), но имеет одну принципиальную проблему: модель пользователя самого практически нереально расширять.1 Пока из адекватных рабочих путей (т.е. даже если смотреть по сторонам, не обращая внимания на слова “гарантированный”, “официальный”, “документированный” ;) есть только создание отдельной модели - профиля (всем заинтересованным - читать пост Джеймса Беннетта, благо он хорошо описал2), но при этом сразу возникает другая проблема - профиль, живущий в отдельной модели, подтягивается к объекту юзеру в общем случае отдельным запросом.

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

Штука эта - несколько функций, которые позволяют загружать обратные связи за один запрос. Т.е. если мы получаем 5 постов в блог, а потом к ним комментарии - это выходит 2 запроса в базу, а не 6 (1 на посты и 5 на комментарии к каждому). В принципе, никакого rocket science’а нету, но я за время работы с джангой всегда изворачивался другим образом, если попадал на подобные грабли - не всегда это было лучше, но кое-как выходило. :-) И вот эти функции я использовал для подгрузки профилей к пользователям в отображении комментариев здесь, что уменьшило количество запросов на каждый пост в разы. :)

Я ещё успел натолкнуться на проблему, что рассчитано это было на что-то подобное “последним двадцати постам или картинкам” - уникальным объектам, и из-за этого кэш получал только первый объект из тех, кто его хотел. А в случае с комментариями такое не прокатывает никак, тут один и тот же человек комментирует несколько раз. :-) Это меня и заставило разобраться в коде и добавить поддержку неуникальных объектов.

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

P.S.После написания этого поста и игр с sup мне захотелось сделать сноски, подобные тем, что есть у Адама Гомаа. :-)

1 -

мне кажется, что с помощью переделки модели юзера в создающуюся динамически эту проблему можно решить.

2 -

хотя я использую AutoOneToOneField Ивана Сагалаева, но большой роли это не играет. :)