Среды Web-разработки на языке Python : Часть 2. Разработка для Web с помощью TurboGears и Python

Основы разработки на примере приложения онлайн-магазина

Во второй статье данного выпуска, мы продемонстрируем TurboGears, другую среду разработки Web-приложений в стиле шаблонов модель-вид-контроллер (model-view-controller - MVC) с открытым исходным кодом, работающий на языке программирования Python. Первая статья была введением в среду разработки Django, в этой же статье будет показано использование TurboGears для создания приложения Web-магазина, и в заключении будет приведено сравнение Turbogears и Django.

Йен Маурер, Senior Consultant, Brulant, Inc.

Йен Маурер (Ian Maurer) - главный консультант в Brulant, Inc., где он специализируется на интегрированных решениях в электронной коммерции (e-commerce), использующих открытое ПО и технологии IBM WebSphere в различных отраслях, включая товары широкого потребления и розничную торговлю. Йен проживает в северо-восточной части штата Огайо (Ohio) и является членом Cleveland Area Python Interest Group.



15.03.2007

Разработчики TurboGears называют этот проект "мегасредой" потому что она создана из нескольких существовавших ранее подпроектов. TurboGears помогает соединить вместе несколько важнейших компонентов:

  • MochiKit: библиотечная реализация JavaScript
  • Kid: язык шаблонов
  • CherryPy: базовая Web-среда разработки
  • SQLObject: библиотека объектно-реляционного преобразования (ORM)

Установка TurboGears

Первое, что понадобится вам для работы с TurboGears - это установленный Python. Последняя версия TurboGears требует Python 2.4. Ссылка на домашнюю страницу Python приведена в разделе Ресурсы.

Setuptools - это новый проект Python-сообщества, который намного упрощает процессы установки и обновления программ на Python. Программа пакуется в файл-архив, называемый Egg (яйцо), подобный файлам JAR в языке Java™ или файлам GEM в языке Ruby. Этот файл легко скачивается и устанавливается с помощью утилиты easy_install.

TurboGears - один из первых больших Python-проектов, использующих setuptools для распространения и установки. Ссылки на страницу setuptools и страницу для скачивания TurboGears имеются в разделе Ресурсы.

В данной статье используется последняя разработочная версия на момент написания статьи (0.9a5), которую мы скачали со страницы скачивания предварительных версий:

easy_install -f http://www.turbogears.org/preview/download/index.html TurboGears

Чтобы скачать новейшую стабильную версию среды TurboGears (в настоящий момент это 0.8.9), просто уберите опцию -f и URL сайта предварительных версий:

easy_install TurboGears

Проверка утилиты администрирования среды TurboGears

После установки TurboGears у вас в списке путей должен появиться путь к утилите администрирования tg-admin. Проверьте это, набрав в командной строке tg-admin:

Листинг 1. Использование утилиты администрирования TurboGears
~/dev$ tg-admin

TurboGears 0.9a5 command line interface

Usage: /usr/bin/tg-admin [command] [options]

Available commands:
      i18n  Manage i18n data
      info  Show version info
quickstart  Create a new TurboGears project
     shell  Start a Python prompt with your database available
       sql  Run the SQLObject manager
   toolbox  Launch the TurboGears Toolbox
    update  Update an existing turbogears project

Приступаем к работе

Чтобы создать новый проект TurboGears, используйте функцию tg-admin quickstart. Вас попросят задать имя проекта и имя каталога. В данной статье я создаю простой пример «корзины для покупок» электронного магазина под названием TG Commerce; соответствующий пакет имеет имя tgcommerce:

Листинг 2. Создание проекта в TurboGears
~/dev$ tg-admin quickstart
Enter project name: TG Commerce
Enter package name [tgcommerce]:
Selected and implied templates:
  turbogears#turbogears  web framework

Variables:
  package:  tgcommerce
  project:  TG-Commerce
Creating template turbogears
  Creating ./TG-Commerce/

    ... (output snipped) ...

TurboGears создает каталог проекта TG-Commerce, внутри которого будет располагаться пакет tgcommerce. Теперь можно запустить тест-сервер, который входит в состав вашего проекта:

Листинг 3. Запуск тест-сервера
~/dev/TG-Commerce$ python start-tgcommerce.py

... (output snipped) ...

05/Mar/2006:11:31:54 HTTP INFO Serving HTTP on http:
//localhost:8080/

Просмотрите тестовую страницу по приведенному выше URL, а затем остановите сервер с помощью Ctrl-C.


Создание модели

SQLObject представляет собой библиотеку объектно-реляционного преобразования (ORM), которая позволяет создавать объекты Python, сохраняемые в базе данных. Вы определяете класс на Python, добавляете необходимые вам атрибуты (поля), а затем SQLObject автоматически формирует нужный SQL-код для создания таблиц, добавления новых записей, нахождения, изменения и удаления записей.

SQLObject поддерживает несколько баз данных, включая MySQL, PostgreSQL, Firebird и другие. Более подробную информацию по SQLObject можно найти по соответствующей ссылке в разделе Ресурсы.

В этом примере я использую в качестве базы данных SQLite. SQLite - это компактная база данных, не требующая конфигурирования и размещающаяся на диске в виде простого файла. Чтобы использовать SQLite, установите библиотеку pysqlite с помощью setuptools:

easy_install pysqlite

Для конфигурации базы данных TurboGears задайте sqlobject.dburi в файле dev.cfg. Для SQLite задайте путь к месту, где вы хотите разместить файл базы данных:

Листинг 4. Файл конфигурации разработки (dev.cfg)
sqlobject.dburi="notrans_sqlite:///path/to/devdir/
TG-Commerce/tgcommerce.database"
server.environment="development"
autoreload.package="tgcommerce"

Процедура quickstart TurboGears проекта TurboGears создает файл model.py и заполняет его стандартным кодом. В этом файле размещаются классы SQLObject. В начале файла находится раздел, который задает узел подключения (connection hub) базы данных:

Листинг 5. Стандартный код модели (model.py)
from sqlobject import *
from turbogears.database import PackageHub

hub = PackageHub("tgcommerce")
__connection__ = hub

Затем следуют классы модели. Каждый из них представляет собой таблицу в базе данных; при этом атрибуты уровня классов отображаются в поля базы данных. Эти атрибуты являются экземплярами типов полей SQLObject. В число этих типов входят базовые типы данных, такие как StringCol и CurrencyCol, и типы отношений, такие как ForeignKey и MultipleJoin.

В нашем приложении магазинной корзины имеется иерархический класс Category (Категория) и простой класс Product (Товар). Иерархия категорий задается родителем ForeignKey и подкатегориями MultipleJoin.

Листинг 6. Классы Category и Product (model.py, продолжение)
class Category(SQLObject):
    name = StringCol(length=64)
    parent = ForeignKey('Category', default=None)
    subcategories = MultipleJoin('Category', 
    joinColumn='parent_id')
    products = MultipleJoin('Product')

class Product(SQLObject):
    name = StringCol(length=64)
    sku = StringCol(length=64)
    price = CurrencyCol(notNone=True, default=0.0)
    category = ForeignKey('Category')

Чтобы удостовериться в правильности модели, введите команду tg-admin sql sql; она выведет код SQL, создающий необходимые таблицы. Отметим, что SQLObject создает для каждой таблицы столбец id (идентификатор). Это происходит, когда первичный ключ не указан. Ссылки на дополнительную документацию по SQLObject приведены в разделе Ресурсы.

Листинг 7. Просмотр схемы базы данных с помощью команды 'tg-admin sql sql'
~/dev/TG-Commerce$ tg-admin sql sql
Using database URI sqlite:///home/ubuntu/dev/
TG-Commerce/tgcommerce.db
CREATE TABLE category (
    id INTEGER PRIMARY KEY,
    name VARCHAR(64),
    parent_id INT
);

CREATE TABLE product (
    id INTEGER PRIMARY KEY,
    name VARCHAR(64),
    sku VARCHAR(64),
    price DECIMAL(10, 2) NOT NULL,
    category_id INT
);

Ниже приведены классы Order (Заказ) и OrderItem (Позиция заказа), которые используются для хранения корзины и ее товаров. Так как order в SQL является ключевым словом, мы переопределяем имя таблицы для класса Order в orders, используя атрибут таблицы подкласса sqlmeta:

Листинг 8. Классы Order и OrderItem (model.py, продолжение)
class Order(SQLObject):
    items = MultipleJoin('OrderItem', joinColumn='order_id')

    class sqlmeta:
        table = 'orders'

class OrderItem(SQLObject):
    quantity = IntCol(notNone=True)
    price = CurrencyCol(notNone=True)
    total = CurrencyCol(notNone=True)
    order = ForeignKey('Order')
    product = ForeignKey('Product')

С помощью команды tg-admin sql create создайте таблицы базы данных:

Листинг 9. Создание таблиц базы данных с помощью команды 'tg-admin sql create'
~/dev$ tg-admin sql create
Using database URI sqlite:///home/ubuntu/dev/
TG-Commerce/tgcommerce.db

Введя команду tg-admin sql help, можно вывести список других команд, включая команду для сброса таблиц. Будьте очень осторожны при использовании этой команды, так как она удалит все ваши таблицы вместе с данными. Уже по этой единственной причине в рабочей среде команду tg-admin следует заблокировать.


Управление моделью с помощью CatWalk

Начиная с версии 0.9 вместе с TurboGears поставляется набор утилит Toolbox, в состав которого входит браузер моделей CatWalk. CatWalk - это инструмент с графическим интерфейсом для разработчиков, позволяющий быстро создавать, обновлять и удалять данные моделей.

Toolbox запускается как отдельный сервер при помощи команды tg-admin:

Листинг 10. Запуск сервера toolbox с помощью tg-admin
~/dev/TG-Commerce$ tg-admin toolbox
... (snip) ...
05/Mar/2006:15:01:33 HTTP INFO Serving HTTP on
 http://localhost:7654/

Если браузер не откроется автоматически, перейдите по адресу (http://localhost:7654/), указанному сервером Toolbox, и нажмите на ссылку CatWalk, чтобы его открыть.

Рисунок 1. Утилита CatWalk
Утилита CatWalk

Toolbox адресован разработчикам, а не конечным пользователям, и его лучше всего использовать как вспомогательный инструмент при моделировании данных и начальной загрузке данных вашего приложения. Вы можете отключить сервер toolbox с помощью Ctrl-C; в данном примере он не понадобится.


Создание представления

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

В среде TurboGears файлы языка Kid располагаются в каталоге шаблонов и имеют расширение .kid. Пол умолчанию существуют файлы master.kid и welcome.kid, где master.kid является базовым файлом шаблонов, а welcome.kid наследует от него при помощи атрибута py:extends в теге <html>.

Чтобы создать новый шаблон, для начала я рекомендую вам скопировать или переименовать файл welcome.kid в файл своего шаблона. Для настоящего примера сначала был создан шаблон категории, который отображает следующую информацию о категории:

  • Имя категории (заголовок и отладочная метка (breadcrumb))
  • Ссылки на прародителей (отладочные метки)
  • Ссылки на подкатегории (список)
  • Ссылки на товары (список)
Листинг 11. Файл со страницей категорий в формате kid-шаблона (category.kid)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/
    xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:py="http://purl.org/kid/ns#"
    py:extends="master.kid">

<head>
    <title>Category: 
    ${category.name}</title>
</head>

<body>
	<div id="breadcrumbs">
		<ul>
			<li py:for="ancestor in list
			(category.ancestors)[::-1]">
				>
				<a href="/category/$
				{ancestor.id}"
						py:content="
						ancestor.name"></a>
			</li>
			<li id="active">
				> <span py:replace=
				"category.name" />
			</li>
		</ul>
	</div>

	<div id="subcategories" 
	py:if="category.subcategories">
		<div class=
		"header">Subcategories</div>
		<ul>
			<li py:for=
			"subcategory in category.subcategories">
				<a href=
				"/category/${subcategory.id}"
						py:content=
						"subcategory.name"></a>
			</li>
		</ul>
	</div>

	<div id="subcategories" 
	py:if="category.products">
		<div class=
		"header">Products</div>
		<ul>
			<li py:for=
			"product in 
			category.products">
				<a href=
				"/product/${product.id}"
						py:content=
						"product.name"></a>
			</li>
		</ul>
	</div>
</body>
</html>

Листинг 11 показывает некоторые ключевые функциональные возможности языка Kid:

  • Наследование от master.kid с помощью py:extends
  • Подстановка выражений в заголовке с помощью ${category.name}
  • Циклы по родителям, подкатегориям и товарам с помощью py:for
  • Использование логики срезов (slicing logic) для переключения отображения родителей в отладочных метках
  • Заполнение текста ссылок с помощью py:content
  • Полная замена тега span с помощью py:replace

Для того чтобы указанный выше атрибут ancestors был верным, класс модели Category необходимо изменить, включив в него метод _get_ancestors:

Листинг 12. Добавление метода 'get' для атрибута 'ancestors' в класс Category
class Category(SQLObject):
    name = StringCol(length=64)
    parent = ForeignKey
    ('Category', default=None)
    subcategories = MultipleJoin
    ('Category', joinColumn='parent_id')
    products = MultipleJoin('Product')

    def _get_ancestors(self):
	ancestor = self.parent
	while ancestor:
	    yield ancestor
	    ancestor = ancestor.parent

Создание контроллера

Процедура quickstart в TurboGears создает проект с модулем controllers.py, в котором располагается класс контроллера Root. Это основная точка входа для вашего приложения и место, куда добавляются новые методы контроллера.

Ниже приведены два примера методов контроллера, которые связаны с HTML-шаблоном категории через декоратор (decorator) expose среды TurboGears. Методы контроллера возвращают словари, которые используются в качестве пространства имен, или контекста, во время рендеринга указанного Kid-шаблона.

Листинг 13. Класс контроллера
from turbogears import controllers, expose

class Root(controllers.Root):

    @expose("tgcommerce.templates.category")
    def index(self):
	from model import Category
	category = Category.selectBy(parent=None)[0]
	return dict(category=category)

    @expose("tgcommerce.templates.category")
    def category(self, categoryID):
	from model import Category
	category = Category.get(categoryID)
	return dict(category=category)

В среде TurboGears URL точно отображаются на методы и содержатся внутри контроллера Root. Корневой URL / отображается на специальный метод, называемый index. После того как вы добавили метод под названием category к Root, к нему можно обращаться через URL /category. Любой переданный URL, не соответствующий данному методу, вызывает ошибку 404, если только не определен метод default.

Ниже приведены примеры возможных URL-сценариев и их результаты:

  • /: отображает первую категорию без идентификатора родителя
  • /category?categoryID=2: отображает категорию с идентификатором 2.
  • /category/1: отображает категорию с идентификатором 1 (формат имеется начиная с G 0.9)
  • /category: выдает ошибку 500 по причине отсутствия идентификатора категории.
  • /xyz: выдает ошибку 404

На Рисунке 2 показана страница отображения категорий:

Рисунок 2. Отображение категорий
Отображение категорий

Отображение товара

Для страницы отображения товара создается контроллер product, который находит товар в базе данных и передает его в Kid-шаблон product для рендеринга.

Листинг 14. Добавление метода контроллера товара
@expose("tgcommerce.templates.product")
def product(self, productID):
    from model import Product
    product = Product.get(productID)
    return dict(product=product)

Шаблон product.kid содержит таблицу информации о товарах. Обратите внимание на использование форматирования строки в Python для отображения цены с двумя значащими цифрами:

Листинг 15. Файл kid-шаблона страницы категории (product.kid)
<table id="product-info">
  <tr>
    <td class="fld">Name:</td>
    <td class="val"><span py:replace=
    "product.name" /></td>
  </tr>
  <tr>
    <td class="fld">SKU:</td>
    <td class="val"><span py:replace=
    "product.sku" /></td>
  </tr>
  <tr>
    <td class="fld">Price:</td>
    <td class="val">$<span py:replace
    ="'%.2f' % product.price" /></td>
  </tr>
</table>

На рисунке 3 показана страница отображения товаров:

Рисунок 3. Страница отображения товаров
Страница отображения товаров

Исправление ошибок

Единственное, что не предусматривают наши методы контроллера - это возможность выдачи исключения SQLObjectNotFoundget-методами SQLObject. В Листинге 16 показан переработанный вариант кода, который перехватывает это исключение и выдает его в виде исключения NotFound, которое приводит к выдаче обычной ошибки HTTP 404:

Листинг 16. Добавление обработки ошибок в класс контроллера
from model import Category, Product
from sqlobject import SQLObjectNotFound
from cherrypy import NotFound
from turbogears import controllers, expose, url

class Root(controllers.Root):

    @expose("tgcommerce.templates.category")
    def category(self, categoryID):
	try:
	    category = Category.get(categoryID)
	except SQLObjectNotFound:
	    raise NotFound()
	return dict(category=category)

    @expose("tgcommerce.templates.product")
    def product(self, productID):
	try:
	    product = Product.get(productID)
	except SQLObjectNotFound:
	    raise NotFound()
	return dict(product=product)

Другой способ обработки недостающих объектов, помимо выдачи ошибки 404 - это перенаправление. Это делается с помощью метода turbogears.redirect(...):

Листинг 17. Пример перенаправления
from turbogears import redirect
try:
    object = ClassName.get(objectID)
except SQLObjectNotFound:
    raise redirect("/path_to_redirect")

Корзина электронного магазина

Чтобы наша магазинная корзина работала, нам необходимо активировать сессии для сохранения состояния между запросами. Сессии активируются в конфигурационном файле путем установки значения True для параметра session_filter.on.

Листинг 18. Активация сессий в конфигурационном файле (dev.cfg)
session_filter.on = True
sqlobject.dburi="notrans_sqlite:///path/to/devdir/TG-Commerce/tgcommerce.database"
server.environment="development"
autoreload.package="tgcommerce"

Чтобы текущее состояние магазинной корзины отображалось на каждой странице, можно поместить код HTML в файл главного шаблона, вместо того чтобы копировать и вставлять его в каждую страницу:

Листинг 19. Магазинная корзина, включенная в главный kid-шаблон (master.kid)
<html>
  <body>
  ...
	<div id="shopping-cart">
		Shopping Cart:
		<span id="cart-qty" py:content=
		"cart.total_quantity" /> items
		($<span id="cart-amt" py:content
		="'%.2f' % cart.total_price" />)
	</div>
  </body>
</html>

Вышеуказанное изменение шаблона само по себе приведет к ошибке, так как значение cart отсутствует в словарях возвращаемых значений методов контроллера. В Листинге 20 показана модификация метода products, которая позволяет включить корзину, хранимую в настоящий момент в сессии.

Листинг 20. Возвращаемый контроллерами объект магазинной корзины
@expose("tgcommerce.templates.product")
def product(self, productID):
    try:
	product = Product.get(productID)
    except SQLObjectNotFound:
	raise NotFound()
    return self.results(product=product)

def results(self, cart=None, **kw):
    if not cart:
	cart = self.get_cart()
    kw['cart'] = cart
    return kw

def get_cart(self):
    cartID = session.get("cartID", None)

    cart = None
    if cartID:
	try:
	    cart = Order.get(cartID)
	except SQLObjectNotFound:
	    pass

    if cart is None:
	cart = Order()
	session["cartID"] = cart.id

    return cart

Метод results вызывает get_cart, который находит текущий объект Order или создаст новый, если объект не существует или не найден. Такое же изменение следует сделать также в методах index и category.


Добавление в корзину с использованием Ajax

Чтобы наш пример магазинной корзины соответствовал всем модным тенденциям, функция добавления товара в корзину осуществляется с помощью вызова Ajax без обновления страницы. Для непосвященных, Ajax представляет собой метод реализации Web, название которого означает Asynchronous JavaScript + XML. Статья, в которой был впервые введен термин Ajax, есть в списке ссылок в разделе Ресурсы.

В данном примере в качестве транспортного формата используется язык JavaScript Object Notation (JSON), а не XML. JSON требует меньше ресурсов и имеет встроенную поддержку как в TurboGears, так и в MochiKit. Несмотря на то, что использование асинхронного JavaScript вместе с JSON становится все более популярным, скорее всего это сочетание будет по-прежнему называться Ajax по той простой причине, что аббревиатура Ajaj не звучит.

Ниже приведен метод контроллера add_to_cart, который берет указанный товар и добавляет его в текущую корзину сессии. Этот метод возвращает объект корзины вместе с итоговой ценой и количеством товаров в корзине:

Листинг 21. Метод контроллера add_to_cart
@expose()
def add_to_cart(self, productID):
    cart = self.get_cart()

    product = Product.get(productID)
    cart.add_product(product, 1)

    return self.results(cart=cart,
	       price=cart.total_price,
	       quantity=cart.total_quantity)

Отметим, что методу expose не назначено имя шаблона. Это связано с тем, что мы не собираемся вызывать этот метод напрямую из браузера и отображать его в HTML. Если вы решите просмотреть страницу add_to_cart (http://localhost:8080/add_to_cart/1) непосредственно в браузере или с помощью инструмента, подобного curl, вы получите «сырые» данные JSON: {"tg_flash":null, "price":24, "cart":{"id":24}, "quantity":1}.

Вызов JavaScript из клиента (браузера) к методу контроллера add_to_cart на сервере осуществляется очень просто. MochiKit предоставляет функцию loadJSONDoc, которая берет URL и возвращает так называемый задержанный объект. Этот задержанный объект можно использовать для определения метода обратного вызова, когда асинхронный вызов возвращает отклик.

Листинг 22. AJAX-логика магазинной корзины (cart.js)
function addToCart(productID) {
	var deferred = loadJSONDoc
	('/add_to_cart/' + productID);
	deferred.addCallback(updateCart);
}

function updateCart(results) {
	$("cart-amt").innerHTML
	 = numberFormatter("#.00")(results["price"]);
	$("cart-qty").innerHTML
	 = results["quantity"];
}

Функция updateCart вызывается после возврата; при этом значения JSON передаются в виде переменной ассоциативного массива results. Эта функция обновляет количество товаров в корзине и суммарную стоимость по идентификатору и атрибуту innerHTML. Наконец, с помощью полезной функции MochiKit numberFormatter задается количество значащих цифр цены.

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

Листинг 23. Добавление к странице товара (product.kid) JavaScript-вызова добавления товара в корзину
<head>
    ...
    <script src="/tg_js/MochiKit.js" 
    type="text/javascript" />
    <script src="/static/javascript/
    cart.js" type="text/javascript" />
</head>
<body>
    ...
    <table>
	...
		<tr>
			<td colspan="2"
			 align="right">
				<a href="#" 
				onclick="addToCart
				(${product.id})">
				Add To Cart</a>
			</td>
		</tr>
	</table>
</body>

Заключение: Сравнение TurboGears и Django

И Django, и TurboGears представляют собой среды разработки MVC-типа, которые позволяют динамично и быстро разрабатывать Web-сайты с помощью языка Python. Чтобы выбрать подходящую среду для ваших потребностей, имейте в виду следующие различия:

  • Историческая справка:

    Оба эти проекта, подобно Ruby on Rails, были извлечены из существующих приложений и выпущены в мир программного обеспечения с открытым кодом. Django существует дольше и изначально появился из онлайновой газеты, которая показывала миллионы страниц в день. В свою очередь, проект TurboGears возник из «толстого» клиентского приложения для чтения новостей RSS, которое все еще находится в разработке. В развитии TurboGears сообщество открытого ПО принимает большее участие, чем в Django, потому что он был создан из уже существовавших компонентов с открытым кодом.

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

  • URL:

    Механизм отправки запросов в TurboGears использует класс контроллера и имена методов. Как только вы добавили класс контроллера или метод, он автоматически становится доступным. Если вам необходимо изменить путь, по которому вызывается какой-либо контроллер, вам придется переконфигурировать структуру кода. С другой стороны, в Django имеется отдельный файл конфигураций на основе регулярных выражений, который служит для отображения адресов URL на программный код. Таким образом, структура путей адресов URL оказывается отделена от фактической реализации.

    Система TurboGears быстрее настраивается, чем Django, так как в ней для создания новых страниц необходим только декоратор expose. Однако система конфигурирования в Django обеспечивает максимальную гибкость и управляемость. Адреса URL в Django легко переназначить даже после основательной переработки приложения. Это помогает предотвратить появление "испорченных ссылок", возникающих из-за старых закладок или кэшированных результатов механизма поиска. "Испорченные ссылки" существенно влияют на интенсивность трафика и удобство использования контент-ориентированных Web-сайтов, для создания которых и была спроектирована система Django.

  • Многократное использование кода:

    Команда разработчиков TurboGears называет свой проект мегасредой (megaframework), чтобы подчеркнуть, что TG был собран из уже существующих компонентов. Команда TurboGears отбирает и соединяет самые лучшие доступные компоненты с открытым исходным кодом, вместо того чтобы писать код самостоятельно. Дополнительное преимущество TurboGears состоит в том, что он является мегапроектом, который поддерживает мегасообщество. Проект TG стал мощным центром притяжения, поддерживающим интерес ко всем компонентам, которые составляют TurboGears. Это волна, которая поднимает все корабли.

    С другой стороны, система Django была создана еще в 2003 году, когда компоненты языка Python не были такими устоявшимися, как сейчас. Web-стек в Django был создан с нуля, и в результате мы имеем стабильную среду разработки, на основе которой уже создан ряд Web-сайтов, обслуживающих миллионы обращений ежедневно. Однако некоторые считают, что проект Django может пострадать от синдрома NIH (Not Invented Here - Изобретено Не Здесь) по причине недостаточного повторного использования кода. Но позиция команды Django состоит в том, что работа по созданию среды разработки на Python с нуля ничуть не сложнее склеивания вместе существующих компонентов, и что конечный результат представляет при этом гораздо более единую и связную среду разработки.

  • JavaScript:

    В TurboGears центральное место занимает JavaScript-библиотека MochiKit. Команда разработчиков также создала библиотеку "виджетов", которая широко использует JavaScript для создания функционально насыщенных элементов форм. Это показывает, насколько важную роль в мире TurboGears играет разработка приложений для "толстых" клиентов (Ajax). Команда Django не стала включать в свою среду какую-либо JavaScript-библиотеку по умолчанию, хотя такая возможность обсуждалась. В то же время ни один из этих проектов ни в коей мере не ограничивает вас в использовании любых JavaScript-библиотек.

  • Инструменты администрирования:

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

  • Лицензия:

    Поскольку проект Django был создан «с нуля», он распространяется под единой Open Source-лицензией (лицензия BSD). TurboGears, который был создан из множества разных проектов, имеет несколько лицензий. ORM-инструмент SQLObject распространяется на условиях LGPL (Lesser General Public License), которая требует, чтобы любые изменения, внесенные в исходный код распространяемой библиотеки SQLObject, публиковались для общего пользования. Данная лицензия не требует, чтобы приложения, использующие библиотеку, имели открытый исходный код. Несмотря на это, некоторые компании блокируют использование ПО, имеющего лицензию LGPL. В таких случаях вы можете использовать SQLAlchemy, другой ORM-инструмент с мощной поддержкой в TG-сообществе.

  • Примеры из практики:

    В разделе Ресурсы приведены ссылки на страницы со списками сайтов, созданных на основе Django и TurboGears. Эти работающие приложения демонстрируют, что может быть сделано с помощью каждого из этих средств.

Ресурсы

Научиться

Получить продукты и технологии

  • Python.org является домашней страницей языка программирования Python, где вы можете найти ссылки для скачивния интерпретатора языка Python и стандартные библиотеки.
  • TurboGears.com является домашней страницей среды разработки TurboGears.
  • Kid является шаблонным языком в TurboGears на основе XML.
  • CherryPy является объектно-ориентированной средой Web-разработки на основе языка Python, которая представляет собой базу среды TurboGears.
  • MochiKit является хорошо протестированной JavaScript-библиотекой, которая имеет поддержку DOM и Ajax.
  • JSON (JavaScript Object Notation) является легким форматом обмена данных, который использует MochiKit и TurboGears в асинхронной передачи сообщений.
  • Доступное пробное ПО IBM для скачивания прямо с сайта developerWorks, чтобы вы могли создавать следующие разработки под Linux.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=201987
ArticleTitle=Среды Web-разработки на языке Python : Часть 2. Разработка для Web с помощью TurboGears и Python
publish-date=03152007