Известно мнение, что Джанго не подходит для написания "наколеночных" проектиков, которым не нужно ничего особенно, кроме вывода HTML'а. Создание скелета проекта на Джанго считается работой, достаточно существенной для того, чтобы не заниматься ею ради пары функций.
Мне всегда было "очевидно", что это не так, но недавно по оброненной коллегой фразе я понял, что это не значит, что это очевидно всем. Многие просто не задумываются об этом. Ну, вы знаете, как это бывает… Поэтому я хочу продемонстрировать создание Джанго-проекта минимальными усилиями.
Упрощение
-
Нужно отказаться от команды startproject. Она создаёт хороший скелет проекта с аннотированным файлом настроек, но если вы Джанго-проект видите не впервые, этим можно пренебречь.
-
Файл manage.py — тоже не нужен, это просто локальный хелпер для django-admin.py
-
Не нужно думать о проекте, как о контейнере для приложений, а следовательно не нужно оформлять свой код, как подключаемое приложение. Приложения — одна из самых сильных архитектурных черт Джанго, но для мелких задач эта гибкость никогда не понадобится.
В итоге мы имеем что-то такое:
-
settings.py:
DEBUG = True ROOT_URLCONF = 'urls' TEMPLATE_DIRS = ['.']
-
urls.py:
from django.conf.urls.defaults import * import views urlpatterns = patterns('', (r'^$', views.index), (r'^test/(\d+)/$', views.test), )
-
views.py:
from django.shortcuts import render def index(request): return render(request, 'index.html', {}) def test(request, id): return render(request, 'test.html', {'id': id})
Это — полностью рабочий Джанго-проект. Запускается командой:
django-admin.py --settings=settings runserver
Вы получаете джанговский конвейер request-response, шаблоны. Также ничто не должно мешать работать такой хорошей вещи, как библиотека форм, хотя реально я не проверял. Что вы теряете — так это ORM и завязанные на него приложения. Но на то эта задача и "микро".
Экстремальщина
Чтобы нащупать границу того, когда идея дойдёт до абсурда, я решил ещё собрать всё приложение в один самозапускающийся файл. И у меня вышло:
- web.py:
#### Setup from django.conf import settings if not settings.configured: settings.configure( DEBUG = True, ROOT_URLCONF = 'web', TEMPLATE_DIRS = ['.'], ) from django.conf.urls.defaults import patterns urlpatterns = patterns('', (r'^$', 'web.index'), (r'^test/(\d+)/$', 'web.test'), ) #### Handlers from django.shortcuts import render def index(request): return render(request, 'index.html', {}) def test(request, id): return render(request, 'test.html', {'id': id}) #### Running if __name__ == '__main__': from django.core.management import execute_from_command_line execute_from_command_line()
Файл запускается так:
python web.py runserver
Впрочем, особенной радости от такой сборки я не увидел. Чтобы файл читался, его приходится делить на именованные секции, что как бы говорит нам о том, что это таки должны быть разные файлы. Плюс, написать такой файлик из головы я бы всё равно не смог из-за того что много надо делать по памяти: защита от двойной конфиграции настроек, длинные импорты и т.д.
Но как факт — забавно :-).
Побочная идея
Копаясь с инициализацией проекта я обнаружил, что настройка ROOT_URLCONF
используется в самом ядре обработки запроса. Это привязывает работу Джанго к наличию реального модуля с определённой в нём переменной urlpatterns
. Джанго была бы гибче, если бы конфигурацию URL'ов можно было инициализировать программно простым списком:
settings.configure(
DEBUG = True,
urlconf = [
(r'^$', index),
],
)
Это, наверное, было бы даже полезно на практике, когда среду нужно уметь создавать на лету. Например, при тестировании.
Комментарии: 14
Кончится всё конкурсом в стиле "во сколько байт можно запихнуть работающую программу на джанго?" :)
Что мешает подключить? :) Я всегда рассматривал Django не как монструозный швейцарский нож, а как конструктор, по умолчанию собранный в самой удобной конфигурации. Да, некоторые его части не совместимы со сторонними кубиками, но это не проблема. Этакий Lego от веб-разработки.
Для этого уже нужно приложение с собственным именем и models.py. Не то чтобы это было плохо, но это уже не "простенькое" решение.
При всем уважении к django, я думаю, что для таких мелочей приятнее использовать webpy.org, так как ~50k кода фреймворка дают возможность делать небольшие и гибкие штуковины и не подталкивают к написанию еще чего-то, потому что фреймворк дает возможность это сделать. Конечно никаких сомнений нету, что при помощи django все это тоже можно реализовать, но имея кучу инструментов тяжело остановится на только действительно необходимых и сделать задачу не "приукрасив" ее.
Легким движением руки Джанго превращается... превращается... Джанго превращается... в Синатру! http://www.sinatrarb.com/
Ну это на правах холивара, разумеется :)
Всё равно получается несколько громоздко. Как мне кажется, для подобных задач лучше всё-таки использовать что-нибудь вроде Flask или webpy. И с wsgi вопрос сразу решается :)
Я бы предпочёл Bottle.py для таких задач.
Спасибо! Действительно получаются довольно красивые микро-решения.
Хотя я в последних двух подходящих случаях пользовал tornado.
Про manage.py и startproject - точно, нафиг не нужны.
А вот заголовок у поста обманчивый. Это микроприложение, а не микрофреймворк. Точно так же как никто не обязывает писать огроменные энтерпрайзы там, где достаточно
Иван, спасибо за эксперементирование. Я считаю, что уж если на сервере стоит Django, то смысла ставить Flask или webpy немного. В них надо копаться, натыкаться на ограничения и тонкости. А тут - всё же привычная среда.
Или можно использовать пирамиду[1], в отличии от этого урезанного комбайна.
Николай Яремко упоминал на субботнике подобный (свой) проект: http://www.github.com/makiwara/protosome Правда он чуть-чуть больше, ну и сложнее соответственно.
А запускать лучше указав каталог проекта: django-admin.py runserver --pythonpath=/myprojects/mini --settings=settings
а еще можно нафиг удалить файл views.py и использовать 'direct_ to_template' в urls.py:
оффтоп: оказывается если слово начинается и заканчивается нижним подчеркивание, в нотации markdown оно превращается в слово. Что еще хуже — 'direct(нижнее подчеркивание)to(нижнее подчеркивание)template' превращается в 'directtotemplate'
Отличный пост! Сделал один проект на Bottle, компактно, конечно, но концепция DRY там не работает ( Написал кучу всего, что обычно в джанге не делал. И не нравится в Bottle, что нарушается концепция "Явное лучше, чем неявное". Там дюжина способов извлечь данные запроса! Не хорошо ( Вывод: если знаешь Django, то используй его. В микро, макро, и любом другом масштабе. Это реально хороший фреймворк.