Регистрация - Вход

Реклама на сайте


Django


Давно хочу написать про Django. В итоге, вот, сподвигся, прочитав песню о Ruby и Rails на Julik Live. Многим людям, особенно занимающимся программированием, дизайном и прочей деятельностью, связанной с hi-tech творчеством, думаю, знакомо ощущение, что ты в этом мире катастрофически не успеваешь за временем. Что, в общем-то, и понятно: благодаря интернету творческим людям делиться интересными мыслями становится крайне просто. Усваивать такое количество информации одному человеку почти нереально, поэтому все мы, наверное, осознанно или нет, выработали какие-то механизмы фильтрации, по поводу чего можно просто подумать “да, прикольно…”, а чем заинтересоваться поподробнее.

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

“Таки” в словах “таки пошел” означает, что я, в общем-то, не особенно западаю на объявления о новых веб-фреймворках. Действительно их существует просто дикое количество. Такое ощущение, что каждый веб-разработчик считает своим святым предназначением выдрать куски кода из какого-то своего очередного сайта и объявить их тулкитом, фреймворком, CMS или чем там еще… Документация не прилагается, рефакторинг — “планируется”. Нет, безусловно есть и хорошие, и даже, наверное, очень много. Но обилие плохих поделок сильно снижает вероятность благополучного исхода знакомства.

Но с Django у меня вышло иначе. Я не только про него прочитал, но и решил после этого даже с ним поработать! Что еще более невероятно, я, который может с легкостью рассказать, чем я по уши загружен на ближайшее десятилетие, все же начал с ним работать. И уж совсем из области фантастики то, что все не остановилось на уровне прототипа в моем ноутбуке, а движется к завершению в виде коммерческого проекта фотосервиса (не спрашивайте подробней, что за проект: не могу говорить).

Ruby on Rails

Если вы занимаетесь web-разработкой, умеете пользоваться интернетом и не считаете, что ASP.NET или PHP — самое последнее слово в веб-технологиях, то вы слышали о “Ruby on Rails“. Трудно было не слышать, потому что восторгов и отзывов по поводу того, как просто, быстро и без потери масштабируемости можно писать на RoR веб-приложения, в сети — море.

Меня огорчало только одно: какое-то время назад, решив поменять ориентацию, я заинтересовался не Ruby, а Python’ом. И возможно, я уже слишком “старый” по программерским меркам, поэтому начинать учить другой язык, не разобравшись с первым, мне стало лениво. Да, в общем-то, и смысла особенного не видел, потому что Питон, как язык, очень мне нравится.

Но так или иначе, не успев даже как следует обидеться на судьбу за то, что соседняя очередь опять идет быстрее, я читаю про Django, о котором, как только он появился, говорят не иначе как “очень похоже по идеологии на RoR” и “как RoR, только для Питона”. Это, после совета авторитетов, стало вторым побуждающим фактором к скачиванию.

Вообще, напрямую сравнивать оба фреймворка я не возьмусь, потому что Rails я не использовал, а только видел знаменитый скринкаст на сайте и читал отзывы и сравнения. Однако вот краткая выжимка того, что я знаю об отличиях Rails и Django:

  • Rails изначально вырос из веб-приложения, системы управления “Basecamp“, а Django — из CMS для издательской компании “World Online“. Отсюда некоторые отличия в вещах, которые у той и другой системы получается лучше всего. Как сказал создатель Rails: “Rails больше подходит для создания приложений с добавлением статических страниц, а Django — для контент сайтов с динамическими функциями”.

Взять, например, такую деталь: время жизни пользовательской сессии в Django стоит по умолчанию на 2 недели и считается от первого входа пользователя. Это не очень удобно для приложений, где сеансы короткие (порядка минут-часов), и время “протухания” считают обычно от последнего обращения.

Однако надо учесть, что обе системы активно развиваются, и потихоньку приобретают все нужные черты, которых не имели раньше. Та же поддержка коротких живых сессий в Django уже есть (не без моего участия :-) )

  • В Django модель данных вашего приложения описывается в Питоне классами, и по ней генерится схема БД. А раз схема определяется в языке и от БД не зависит, это значит, что можно легко перейти на другую БД (например если вы писали что-то с Postgres’ом, а у юзера вдруг оказался только MySQL). Еще лично мне это очень нравится из-за того, что я не в состоянии запомнить, как пишутся все эти ALTER TABLE, которые еще и разные для разных БД. Хотя это и решается визуальными конструкторами.

RoR делает по-другому: там сначала пишется схема БД, а по ней генерируется скелет приложения.

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

c7ea58bb22cd8d/65347bcae8303479?&rnum=1#65347bcae8303479

Философия Django

Вот где Django сходится с Rails, так это в идеологии (от чего, собственно, их все и сравнивают). Вот основные принципы Django.

  • Принцип DRY — Don’t Repeat Yourself. Означает, что по возможности надо стараться исключать дублирование уже введенного в систему знания. Самый простой пример, если вы описали тип поля в таблице, вам уже не нужно писать исключительную по своему творческому заряду вещь:

    if тип поля EMail:
    
        проверить, что передан EMail
    
    elif тип поля Integer:
    
        проверить, что передан Integer
    
    ...
    

Фреймворк делает максимум усилий для того, чтобы из описанной один раз информации достать максимум возможного сервиса. Хотя вы можете им и не пользоваться (что тоже иногда важно).

  • Реализация идеологии MVC. Очень удачная и практичная идеология. В Django правда, она реализована не совсем в классическом варианте. Например то, что обычно называется Controller, там вырождено в файл соответствия URL’ов обрабатывающим функциям, которые лежат в уровне View. Поэтому часто говорят, что Django просто переназвали Controller во View, а View — в шаблоны.

  • Разделение фреймворка на максимально независимые компоненты: так называемая “слабая связанность”. Тоже очень правильная идеология. Шаблоны, обработчики и модель почти не завязаны друг на друга. Модель ничего не знает о такой вещи, как HTTP-запрос, а из шаблона нельзя даже случайно изменить данные.

  • Отказ от завязывания шаблонов на язык программирования. Когда шаблон представляет собой смесь HTML’а и кода серверного языка, то очень быстро это приводит к тому, что в шаблон проникает довольно много логики, которой неплохо бы быть на уровне приложения. Что в свою очередь ведет к тому, что все это сложно поддерживать (примерно как суп вилкой есть). В Django язык шаблона вообще не связан с Питоном, а шаблонная логика намеренно очень ограничена. Например в операторе {% if %} можно проверить только логическую истинность объекта, а произвольное условие типа “равна ли длина списка пяти” — не допускается. Еще одно свойство шаблонной системы — безопасность. Можно обращаться не к любым методам, а только к тем, которые не меняют сами объекты. Поэтому шаблон спокойно можно отдать на редактирование кому-то другому, зная, что он ничего не сломает.

  • Красивые URL’ы. Это одна из тех вещей, про которую все знают, что это хорошо, но тем не менее обычно откладывают, потому что на функциональность сайта это не влияет, а начальство требует все новых возможностей от продукта, красота никого не трогает. В Django вы просто не сможете породить конструкции типа “index.php?func=user&subfunc=add&PHPSESSIONID=…..”. У вас есть файл, в котором просто пишется список всех видов URL’ов, которые привзяываются к своим обрабатывающим функциям. Причем изменяемые части URL’ов (id’шки там всякие) передаются в обработчики в виде обычных параметров функций, их не надо доставать из какой-нибудь коллекции.

И еще там есть много вкусных вещей, которые заставляют вас, читая, кивать головой, думая “ага, правильно!” :-).

Less code

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

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

Кроме того, Django поставляется с немалым количеством уже написанных базовых вещей, которые в том или ином виде присутствуют почти в любом современном веб-приложении:

  • Сессии. Вы просто подключаете в приложение нужный модуль и у вас в каждом запросе появляется request.session, в которую можно класть любые данные. Они, естественно, разные для каждого юзера.

  • Авторизация . Вообще чумовая штука: регистрация, авторизация, система прав на объекты вашей модели данных, генерация паролей, рассылка сообщений юзерам по EMail.

  • Кеширование. Для того, чтобы не обращаться в базу каждый раз, когда требуются редко меняющиеся данные, можно вывод закешировать. Можно целиком весь сайт, можно отдельные страницы, можно вообще произвольные данные. Причем у системы кеша еще и несколько возможных вариантов, где этот кеш хранить: в памяти, в memcached (не знаю, что это, но говорят, известная штука), в директории на диске, в таблице БД…

  • И куча еще: синдикация, GZip, conditional get, редиректы, статические информационные страницы, валидация форм и т.д.

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

Но пожалуй, самая “презентационная” особенность Django, ускоряющая разработку сайта — админка. Все, кто пишет веб-приложения, знают сколько времени может отнять написание рабочего места для человека, который будет рулить наполнением табличек. А если это еще и на права завязано…

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

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

Python

Не последнюю роль в реализации принципа “меньше кода — больше денег” играет язык программирования.

Питон — один из модных объектно-ориентированных динамических языков, который отличается от классических (Паскаль, Си, Си++) в первую очередь тем, что он современный. А значит, в нем исправлены многие вещи, которые были сделаны в тех языках плохо. Кроме того, многие приемы программирования (паттерны), которые сложились за долгое время, добавлены прямо в синтаксис языка.

Причем все это сделано не сумбурно, а с наличием четко выверенной позиции, что делает программирование несказанно более простым и предсказуемым. Одни из главных принципов Питона: “явное лучше неявного” и “должен быть только один очевидный способ делать одну вещь”. Поэтому он и не превращается в Perl, который известен как “write-only language”.

Django использует возможности Питона на всю катушку. Например взможность по объекту узнать всю внутреннюю структуру класса, какие у него методы и свойства, очень полезна для реализации принципа DRY. Именно из-за этого возможно строить модель данных по описанным классам и обвешивать объекты этих классов всякими полезными методами. Например, если вы определили класс Person с атрибутом picture, в котором лежит фотография человека, то Django сделает ему удобные методы get_picture_url(), get_picture_filename().

Буквально недавно я написал один кусочек, которым хочу поделиться в качестве примера совместной работы Django и Питона.

Есть у меня список объектов — уменьшенные копии фотографий — которые я передаю в шаблон. Мне понадобилась оптимизация, чтобы некоторые thumbnail’ы нужно было не передавать полностью, а использовать только их id.

Вот тут начинает работать Питоновская динамика. В список thumbnails я могу класть не только экземпляры класса thumbnail, а вообще говоря, все что угодно. И вместо целиковых thumbnail’ов я могу положить там где надо заглушки с id:

thumbnails=[]                  #создается пустой список

for t in get_thumbnail_list(): #получаются thumbnail'ы из БД

  if <какое-то условие>:

    thumbnails.append(t)

  else:

    thumbnails.append({'id':t.id})  #заглушка в виде стандартного dict

dict - это тип данных в Питоне, который в PHP известен как “массив”, в Perl - как “хеш”, а в C++ ближайшим аналогом является STL’ный “map”.

В самом шаблоне ко всем элементам списка я обращаюсь одинаково: {{thumbnail.id}}, даже несмотря на то, что это по природе совсем разные объекты.

Работает это так. Когда Django’вский шаблон встречает конструкцию {{thumbnail.id}} он делает несколько проверок: 1. Если объект thumbnail - коллекция, и у нее есть ключик ‘id’, достается значение по ключу. 1. Если у объекта thumbnail есть свойство id - берется его значение. 1. Если у объекта thumbnail есть метод id(), то он вызывается и берется его результат. 1. Если бы вместо “id” была цифра, то Django проверил бы еще и элемент списка с этим индексом.

Вкусно, да? :-). В итоге шаблон получается гораздо более читаемым, чем во многих других шаблонных системах.

Дальше — больше. Мне понадобилось, чтобы в списке каждый thumbnail сопровождался еще одним параметром — признаком unchanged. И если добавить в заглушку еще один ключик проблем не представляет (будет {'id':t.id,'unchanged':False}), то у объекта thumbnail никакого такого свойства “unchanged” нет.

В каком-нибудь языке со статической типизацией надо было бы заменить все объекты в списке на некую обертку с дополнительным полем:

ThumbnailWrapper={

  unchanged:bool;

  object:Thumbnail;

}

… и заменить все обращения к элементам списка с просто thumbnail.id на thumbnail.object.id.

В Питоне же можно прямо к существующему объекту просто навесить новое свойство простым присваиванием:

thumbnail.unchanged=True   # у объекта создается новое свойство

Красота!

О стабильности кода

Пока еще Django находится в стадии активной доводки, и еще не дожил до версии 1.0. А это в свою очредь означает, что надо быть готовым к тому, что довольно часто разработчики ломают старые API и подходы в пользу более лучших. При этом ведут документик по несовместимым изменениям.

Это, на самом деле, резко увеличивает фан, и почти не добавляет головной боли, потому что изменения маленькие и логичные. Но если для вас важна стабильность кода, то пока переводить клиентские сервисы на Django я бы все же не советовал.

В заключении

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

Планирую писать про Django и дальше. Спрашивайте, что вам было бы интересно.

Источники:

softwaremaniacs.org/blog/2005/12/08/django/


КОММЕНТАРИИ







Теги


RSS

Архив