Показаны сообщения с ярлыком Pylons. Показать все сообщения
Показаны сообщения с ярлыком Pylons. Показать все сообщения
пятница, 16 декабря 2011 г.
четверг, 13 мая 2010 г.
Разработка веб-приложений на базе Pylons, Python
Этот пост представляет собой объединение ряда моих постов под общей темой в единый материал по Pylons.
1. Почему Python круче Perl в веб-разработке. Статья
2. Почему Pylons/Python круче Rails/Ruby и Catalyst/Perl? Статья
3. Установка Pylons 0.9.7 на Debian 5 Lenny. Статья
4. Использование Pylons в продакшене: paster + Nginx Статья
5. Создание первого контроллера. Статья
6. Работа с шаблонами. Статья
7. Передача переменных из контроллера в шаблон. Статья
8. Обработка GET/POST параметров. Статья
9. Работа с сессиями. Статья
10. Подключение базы данных (PostgreSQL, MySQL). Статья
11. Работа с БД посредством SQLAlchemy. Статья
12. Работа с моделью из внешних скриптов. Статья
13. Подключение ToscaWidgets к Pylons для работы с формами. Статья
14. Валидация форм посредством ToscaWidgets. Статья
15. Аутентификация посредством AuthKit. Статья
16. Авторизация посредством AuthKit. Статья
Есть также идея написать еще посту про пагинацию, кэширование и REST интерфейсы. Если Вам интересно что-то конкретное, то милости прошу в комменты :)
1. Почему Python круче Perl в веб-разработке. Статья
2. Почему Pylons/Python круче Rails/Ruby и Catalyst/Perl? Статья
3. Установка Pylons 0.9.7 на Debian 5 Lenny. Статья
4. Использование Pylons в продакшене: paster + Nginx Статья
5. Создание первого контроллера. Статья
6. Работа с шаблонами. Статья
7. Передача переменных из контроллера в шаблон. Статья
8. Обработка GET/POST параметров. Статья
9. Работа с сессиями. Статья
10. Подключение базы данных (PostgreSQL, MySQL). Статья
11. Работа с БД посредством SQLAlchemy. Статья
12. Работа с моделью из внешних скриптов. Статья
13. Подключение ToscaWidgets к Pylons для работы с формами. Статья
14. Валидация форм посредством ToscaWidgets. Статья
15. Аутентификация посредством AuthKit. Статья
16. Авторизация посредством AuthKit. Статья
Есть также идея написать еще посту про пагинацию, кэширование и REST интерфейсы. Если Вам интересно что-то конкретное, то милости прошу в комменты :)
пятница, 16 апреля 2010 г.
Использование Pylons в продакшене: paster + Nginx
Разработку приложения можно вполне вести и на встроенном веб-сервере paster, но как только посещаемость увеличивается и Вы запускаете проект, то, безусловно, paster - не лучший выбор. Тут ем может помочь Nginx, выступающий в качестве reverse proxy!
Итак, имеем paster на 5000 порту:
Ставим Nginx (здесь и далее - ОС Debian 5 Lenny):
Удаляем конфиг стандартного сайта:
Создаем новый:
Со следующим содержимым:
Перезапускаем Nginx и применяем настройки:
Следом запускаем paster (иначе поулчим на 80м порту "502 bad gateway"):
Все, теперь открываем сайт http://domain.ru и любуемся видом нашего Pylons проекта.
Итак, имеем paster на 5000 порту:
http://127.0.0.1:5000
Ставим Nginx (здесь и далее - ОС Debian 5 Lenny):
apt-get install -y nginx
Удаляем конфиг стандартного сайта:
rm /etc/nginx/sites-enabled/default
Создаем новый:
vi /etc/nginx/sites-enabled/default
Со следующим содержимым:
server {
listen 80;
server_name domain.ru;
access_log /var/log/nginx/access.log;
location / {
# передаем хостнейм Paster, хотя это не обязательно
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:5000;
}
}
Перезапускаем Nginx и применяем настройки:
/etc/init.d/nginx restart
Следом запускаем paster (иначе поулчим на 80м порту "502 bad gateway"):
cd myapp
nohup paster serve --reload development.ini &
Все, теперь открываем сайт http://domain.ru и любуемся видом нашего Pylons проекта.
воскресенье, 14 марта 2010 г.
Pylons: авторизация посредством AuthKit
Задачу с проверкой логина и пароля мы решили в прошлый раз, теперь хотелось бы в зависимости от логина пользователя давать или не давать ему доступ к определенным контроллерам. Действовать мы будем по мануалу: http://pylonsbook.com/en/1.1/authentication-and-authorization.html#the-authorization-decorator
Теперь открываем наш контроллер:
И в блок import ов добавляем следующее:
Теперь мы можем переписать контроллер private в более простом виде :
То есть в декораторе идет проверка является ли юзер залогиненым (установлено ли REMOTE_USER) и только после этого выполняет код метода. При этом в книге по Pylons крайне рекомендуется использовать ValidAuthKitUser() вместо RemoteUser(), так как второй просто проверяет не пустоту поля REMOTE_USER, но не убеждается, что это явно разрешенный в конфиге юзер. Как понимаете, ValidAuthKitUser более безопасен.
Теперь создадим контроллер, который будет доступен только пользователю admin2:
И если же попытаться войти на эту страницу от имени admin, то в ответ мы получим "403 Forbidden".
Кроме подключения авторизации через декораторы возможно ее использование как Middleware, подробно это описано вот здесь: http://pylonsbook.com/en/1.1/authentication-and-authorization.html#the-authorization-middleware
А вот так вот можно закрыть весь контроллер сразу (я крайне долго искал подобную фичу в Catalyst, но не нашел):
Ну вот, пожалуй, и хватит с авторизацией. Но замечу, что кроме описанных фич у AuthKit есть еще очень много всего вкусного, например, группы пользователей / роли (то есть можно гранулировано выдавать полномочия на те или иные подсистемы разным юзерам) / разрешения / поддержка OpenID а также искаробочная возможность привязывать юзеров только к определенным IP.
Теперь открываем наш контроллер:
vi myapp/controllers/main.py
И в блок import ов добавляем следующее:
from authkit.authorize.pylons_adaptors import authorize
from authkit.permissions import RemoteUser, ValidAuthKitUser, UserIn
Теперь мы можем переписать контроллер private в более простом виде :
@authorize(RemoteUser())
def private(self):
return "You are authenticated!"
То есть в декораторе идет проверка является ли юзер залогиненым (установлено ли REMOTE_USER) и только после этого выполняет код метода. При этом в книге по Pylons крайне рекомендуется использовать ValidAuthKitUser() вместо RemoteUser(), так как второй просто проверяет не пустоту поля REMOTE_USER, но не убеждается, что это явно разрешенный в конфиге юзер. Как понимаете, ValidAuthKitUser более безопасен.
Теперь создадим контроллер, который будет доступен только пользователю admin2:
@authorize(UserIn(['admin2']))
def private2(self):
return "You are admin2!"
И если же попытаться войти на эту страницу от имени admin, то в ответ мы получим "403 Forbidden".
Кроме подключения авторизации через декораторы возможно ее использование как Middleware, подробно это описано вот здесь: http://pylonsbook.com/en/1.1/authentication-and-authorization.html#the-authorization-middleware
А вот так вот можно закрыть весь контроллер сразу (я крайне долго искал подобную фичу в Catalyst, но не нашел):
@authorize(ValidAuthKitUser())
def __before__(self):
pass
Ну вот, пожалуй, и хватит с авторизацией. Но замечу, что кроме описанных фич у AuthKit есть еще очень много всего вкусного, например, группы пользователей / роли (то есть можно гранулировано выдавать полномочия на те или иные подсистемы разным юзерам) / разрешения / поддержка OpenID а также искаробочная возможность привязывать юзеров только к определенным IP.
Pylons: аутентификация посредством AuthKit
Есть вот такая отличная библиотека для всего, что только можно вытворить с авторизацией / аутентификацией в веб-приложении (поддерживаются HTTP basic, HTTP digest, form, cookie OpenID ит.д.) http://authkit.org/. Также на офсайте AuthKit явно указано, что с Pylons он работает ну просто супер :) Вот ее мы и будем подключать, хотя есть еще аналоги в лице http://what.repoze.org/docs/1.0/ и http://static.repoze.org/whodocs/ При этом руководствоваться мы будем вот этой инструкцией: http://pylonsbook.com/en/1.1/authentication-and-authorization.html Также в случае проблем с пониманием "куда вставить этот код" использовалась вот эта сборочка: http://pypi.python.org/pypi/SimpleSite/0.3.0
Настроим аутентификацию (просто проверка логина/пароля без контроля прав доступа к различным ресурсам).
Устанавливаем:
Открываем конфигурацию middleware:
Добавляем в самый верх, в блок import:
Также ПЕРЕД блоком:
С аналогичным отступом добавляем подключение auth middleware:
Теперь нам необходимо сконфигурировать AuthKit:
И в самый низ блока "[app:main]" добавляем следующее:
Таким образом мы создали одного пользователя и выбрали тип аутентификации - формы/куки, а также выбрали метод, при вызове которого будет происходить logout.
Теперь открываем наш контроллер:
После этого создаем там методы:
И пробуем открыть его через сеть: http://xx.xx.xx.xx:5000/main/private и там нам будет выдана форма, введя в которую admin/qwerty мы станем аутентифицированным пользователем. Проверка статус аутентификации проверяется по логину, который в случае успешной аутентификации помещается в request.environ.get("REMOTE_USER"). Чтобы "вылогиниться" нам необходимо просто посетить адрес http://xx.xx.xx.xx:5000/main/signout при этом куки файл, хранящий данные о залогинености будет удален.
Все, с аутентификацией закончено :)
Настроим аутентификацию (просто проверка логина/пароля без контроля прав доступа к различным ресурсам).
Устанавливаем:
easy_install authkit
Открываем конфигурацию middleware:
vi myapp/config/middleware.py
Добавляем в самый верх, в блок import:
import authkit.authenticate
Также ПЕРЕД блоком:
# Display error documents for 401, 403, 404 status codes (and
# 500 when debug is disabled)
if asbool(config['debug']):
app = StatusCodeRedirect(app)
else:
app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
С аналогичным отступом добавляем подключение auth middleware:
app = authkit.authenticate.middleware(app, app_conf)
Теперь нам необходимо сконфигурировать AuthKit:
vi development.ini
И в самый низ блока "[app:main]" добавляем следующее:
authkit.setup.method = form, cookie
authkit.form.authenticate.user.data = admin:qwerty
[без выравнивания по = раб. не будут ]admin2:qwerty2
authkit.cookie.secret = secret string
authkit.cookie.signoutpath = /main/signout
Таким образом мы создали одного пользователя и выбрали тип аутентификации - формы/куки, а также выбрали метод, при вызове которого будет происходить logout.
Теперь открываем наш контроллер:
vi myapp/controllers/main.py
После этого создаем там методы:
def private(self):
if request.environ.get("REMOTE_USER"):
return "You are authenticated as %s!" % request.environ.get("REMOTE_USER")
else:
response.status = "401 Not authenticated"
return "You are not authenticated"
def signout(self):
return "Successfully signed out!"
И пробуем открыть его через сеть: http://xx.xx.xx.xx:5000/main/private и там нам будет выдана форма, введя в которую admin/qwerty мы станем аутентифицированным пользователем. Проверка статус аутентификации проверяется по логину, который в случае успешной аутентификации помещается в request.environ.get("REMOTE_USER"). Чтобы "вылогиниться" нам необходимо просто посетить адрес http://xx.xx.xx.xx:5000/main/signout при этом куки файл, хранящий данные о залогинености будет удален.
Все, с аутентификацией закончено :)
Pylons: валидация форм посредством ToscaWidgets
В первой части статьи мы научились просто отображать формы: http://phpsuxx.blogspot.com/2010/03/pylons-toscawidgets.html Теперь мы добавим к этому функцию валидации входных данных от форм. На начальном этапе у Вас должен быть проект со всеми правками с прошлого примера. Руководствоваться мы будем вот этим: http://toscawidgets.org/documentation/tw.forms/tutorials/validate_pylons.html
Открываем код нашего контроллера:
Добавляем в самый верх подключение модуля валидации:
Чуть ниже него добавляем (устанавливаем дополнительный валидатор, чтобы год точно был целым числом):
Также удаляем старый метод tosca и вместо него добавляем следующее:
То есть, если данные валидны (в поле year целое число), они будут переданы обработчику tosca_save и выданы на экран. Иначе будет сделан "редирет" (в кавычках потому что будет просто выдано его содержимое ) на index контроллер. Ну вот теперь у нас есть крайне удобный способ обработки форм без тупой рутины :)
Открываем код нашего контроллера:
vi myapp/controllers/main.py
Добавляем в самый верх подключение модуля валидации:
from tw.mods.pylonshf import validate
Чуть ниже него добавляем (устанавливаем дополнительный валидатор, чтобы год точно был целым числом):
test_form = twf.TableForm('test_form', action='/main/tosca_save', children=[
twf.HiddenField('id'),
twf.TextField('title'),
twf.TextField('year', size=4, validator=twf.validators.Int),
twf.CalendarDatePicker('release_date'),
twf.SingleSelectField('genera', options=['', 'Action', 'Comedy', 'Other']),
twf.TextArea('description'),
])
Также удаляем старый метод tosca и вместо него добавляем следующее:
def tosca(self, **kw):
return test_form()
@validate(form=test_form, error_handler='index')
def tosca_save(self, **kw):
return str(kw)
То есть, если данные валидны (в поле year целое число), они будут переданы обработчику tosca_save и выданы на экран. Иначе будет сделан "редирет" (в кавычках потому что будет просто выдано его содержимое ) на index контроллер. Ну вот теперь у нас есть крайне удобный способ обработки форм без тупой рутины :)
Pylons: подключение ToscaWidgets к Pylons для работы с формами
Есть вот такая обалденная штука: http://toscawidgets.org/ К ней прилагается куча готовых виджетов, их можете найти здесь: http://pypi.python.org/pypi?:action=search&term=tw&submit=search
Ставим сам ToscaWidgets:
Ставим виджет работы с формами (к слову, есть еще tw.dynforms, но о нем, думаю, позже):
Далее двигаемся по инструкции по интеграции ToscaWidgets с Pylons: http://toscawidgets.org/documentation/ToscaWidgets/install/pylons_app.html
Открываем настройки middleware:
Добавляем в самый верх:
Далее после строки "CUSTOM MIDDLEWARE HERE" добавляем следующее:
Теперь открываем контроллер:
И в самый верх добавляем подключение виджета:
И внизу добавляем еще тестовый метод:
И теперь вызываем со сети наш контроллер: http://xx.xx.xx.xx:5000/main/tosca и любуемся довольно миловидными формочками :)
Ставим сам ToscaWidgets:
easy_install ToscaWidgets
Ставим виджет работы с формами (к слову, есть еще tw.dynforms, но о нем, думаю, позже):
easy_install tw.forms
Далее двигаемся по инструкции по интеграции ToscaWidgets с Pylons: http://toscawidgets.org/documentation/ToscaWidgets/install/pylons_app.html
Открываем настройки middleware:
vi myapp/config/middleware.py
Добавляем в самый верх:
import tw.api as twa
Далее после строки "CUSTOM MIDDLEWARE HERE" добавляем следующее:
app = twa.make_middleware(app, {
'toscawidgets.framework': 'pylons',
'toscawidgets.framework.default_view': 'mako',
})
Теперь открываем контроллер:
vu myapp/controllers/main.py
И в самый верх добавляем подключение виджета:
import tw.forms as twf
И внизу добавляем еще тестовый метод:
def tosca(self):
test_form = twf.TableForm('test_form', action='/main/tosca_save', children=[
twf.HiddenField('id'),
twf.TextField('title'),
twf.TextField('year', size=4),
twf.CalendarDatePicker('release_date'),
twf.SingleSelectField('genera', options=['', 'Action', 'Comedy', 'Other']),
twf.TextArea('description'),
])
return test_form()
И теперь вызываем со сети наш контроллер: http://xx.xx.xx.xx:5000/main/tosca и любуемся довольно миловидными формочками :)
суббота, 13 марта 2010 г.
среда, 21 октября 2009 г.
Pylons: CRUD для SQLAlchemy
Итак, мы дошли до самого интересного -- качественного CRUD интерфейса для работы с SQLAlchemy.
Вот ссылка: http://docs.formalchemy.org/current/ext/pylons.html#administration-interface
Запускаем:
И конфигурируем следующим образом:
После этого конфигурируем модель: http://phpsuxx.blogspot.com/2009/10/pylons_18.html
Теперь открываем: http://127.0.0.1/admin
Но у меня закрался баг -- слетели стили и все стало жутко некрасиво (ошибка в стиле: "/admin/_static//admin.css" ).
Переходим в папку cd myapp/public/ и стаскиваем следующие файлы:
Теперь открываем файл admin.css и заменяем все упоминания png файлов с ./edit.png на edit.png
А также добавляем строки:
Теперь идем в папку: myapp/templates/forms/ и открываем файл: restfieldset.mako и там строчку:
меняем на
Итого - вещь ОЧЕНЬ сырая и насмерть завязанная на Mako. Так что ищем альтернативы или пишем сами.
Вот ссылка: http://docs.formalchemy.org/current/ext/pylons.html#administration-interface
Запускаем:
paster create -t pylons_fa myapp
И конфигурируем следующим образом:
Enter admin_controller (Add formalchemy's admin controller) [False]: True
Enter template_engine (mako/genshi/jinja2/etc: Template language) ['mako']: mako
Enter sqlalchemy (True/False: Include SQLAlchemy 0.5 configuration) [False]: True
После этого конфигурируем модель: http://phpsuxx.blogspot.com/2009/10/pylons_18.html
Теперь открываем: http://127.0.0.1/admin
Но у меня закрался баг -- слетели стили и все стало жутко некрасиво (ошибка в стиле: "/admin/_static//admin.css" ).
Переходим в папку cd myapp/public/ и стаскиваем следующие файлы:
wget http://formalchemy.googlecode.com/hg/formalchemy/ext/pylons/resources/edit.png
wget http://formalchemy.googlecode.com/hg/formalchemy/ext/pylons/resources/add.png
wget http://formalchemy.googlecode.com/hg/formalchemy/ext/pylons/resources/admin.css
wget http://formalchemy.googlecode.com/hg/formalchemy/ext/pylons/resources/delete.png
Теперь открываем файл admin.css и заменяем все упоминания png файлов с ./edit.png на edit.png
А также добавляем строки:
.ui-icon-circle-plus {
background-image: url(add.png);
)
Теперь идем в папку: myapp/templates/forms/ и открываем файл: restfieldset.mako и там строчку:
href="${url('fa_static', path_i nfo='/admin.css')}"
меняем на
href="/admin.css"
Итого - вещь ОЧЕНЬ сырая и насмерть завязанная на Mako. Так что ищем альтернативы или пишем сами.
Pylons: работа с формами, FormAlchemy
Обнаружил замечательный инструмент работы с формами: FormAlchemy, он способен генерировать HTML формы из схемы бд SQLAlchemy
Устанавливаем:
Открываем файл:
Теперь внизу добавляем новый контроллер для теста создания формы для добавления нового объекта:
Для редактирования полей существующего объекта используется следующий контроллер:
Также, разумеется, есть возможность изменять данные формы, верифицировать их и вносить измененный объект в базу, эти примеры можете посмотреть на офсайте и на странице проекта.
Тут следует отметить, что FA генерирует только набор полей, но не обрамляет все это в таги form и не добавляет управляющих элементов (submit, cancel).
Итого: штука крайне стремная и крайне сырая и мне НЕ НРАВИТСЯ. Продолжаем поиски дальше :)
Устанавливаем:
easy_install FormAlchemy
Открываем файл:
vim myapp/controllers/main.pyи добавляем в верху подключение модуля:
from formalchemy import FieldSet, Field
Теперь внизу добавляем новый контроллер для теста создания формы для добавления нового объекта:
def form_new(self):
fs = FieldSet(model.Person)
return fs.render()
Для редактирования полей существующего объекта используется следующий контроллер:
def form_edit(self):
my_person = meta.Session.query(model.Person).first()
fs = FieldSet(my_person)
return fs.render()
Также, разумеется, есть возможность изменять данные формы, верифицировать их и вносить измененный объект в базу, эти примеры можете посмотреть на офсайте и на странице проекта.
Тут следует отметить, что FA генерирует только набор полей, но не обрамляет все это в таги form и не добавляет управляющих элементов (submit, cancel).
Итого: штука крайне стремная и крайне сырая и мне НЕ НРАВИТСЯ. Продолжаем поиски дальше :)
Python/Pylons виджет-движок для веб?
Мммм очень интересная штука, концепцию которой я пока не особенно понял:
http://toscawidgets.org/ но подход выглядит очень суперски!
http://toscawidgets.org/ но подход выглядит очень суперски!
Pylons CRUD, как ?
Сейчас наткнулся на вот такое: http://pylonshq.com/project/pylonshq/wiki/LaurentsNotes Комрады, а какие есть готовые CRUD для Pylons/SQLAlchemy?
Вот еще интересная разработка: http://code.google.com/p/pails-admin/
Вот еще интересная разработка: http://code.google.com/p/pails-admin/
понедельник, 19 октября 2009 г.
Pylons: работа с моделью из внешних скриптов
Довольно часто приходится обращаться к данным БД не из MVC фреймворка, а из каких-либо связанных скриптов. Как это делать в случае SQLAlchemy мы разберемся сейчас =)
Переходим в папку проекта (myapp) и создаем файл mydbscript.py следующего содержания:
Делаем скрипт исполняемым и запускаем:
Вот так довольно легко можно получить все прелести ORM из своего скрипта :)
Переходим в папку проекта (myapp) и создаем файл mydbscript.py следующего содержания:
#!/usr/bin/python2.5
# -*- coding: utf-8 -*-
import sqlalchemy as sa
from myapp import model
import myapp.model.meta as meta
DB_URL = "mysql://my_db_user:qwerty@127.0.0.1/my_test_database"
#DB_URL = "postgres://my_db_user:qwerty@127.0.0.1:5432/my_test_database"
engine = sa.create_engine(DB_URL)
model.init_model(engine)
# а далее следует обычный код работы с БД
person_q = meta.Session.query(model.Person)
all_users = person_q.filter(model.Person.name=='Pavel').all()
for user in all_users:
print "User: ", user.name
Делаем скрипт исполняемым и запускаем:
chmod +x mydbscript.py
./mydbscript.py
Вот так довольно легко можно получить все прелести ORM из своего скрипта :)
Pylons: работа с БД средствами SQLAlchemy
Для начала подключаем необходимые для работы классы, в файле
Первое импортирует служебный класс meta, используемый для работы SQLAlchemy, а второе импортирует наши классы модели.
Теперь в файл
Теперь открываем нашу страницу через веб и следим, чтобы все прошло без ошибок:
http://127.0.0.1/main/db_write
Теперь напишем контроллер, который выдаст нам содержимое БД:
Теперь необходимо создать шаблон:
Вот его текст:
Теперь открываем страницу: http://127.0.0.1/main/db_read и любуемся нашим креативом =)
Итак, нам осталось разобраться с формами, пагинацией и все, можно будет приступать к созданию новых клевых сервисов =)
vi myapp/controllers/main.pyв верху добавляем:
from myapp.model import meta
from myapp import model
Первое импортирует служебный класс meta, используемый для работы SQLAlchemy, а второе импортирует наши классы модели.
Теперь в файл
vi myapp/controllers/main.pyдобавляем код записи в БД:
def db_write(self):
new_user = model.Person()
new_user.name = "Pavel"
meta.Session.add(new_user)
meta.Session.commit()
Теперь открываем нашу страницу через веб и следим, чтобы все прошло без ошибок:
http://127.0.0.1/main/db_write
Теперь напишем контроллер, который выдаст нам содержимое БД:
def db_read(self):
person_q = meta.Session.query(model.Person)
c.all_users = person_q.filter(model.Person.name=='Pavel').all()
return render("main/db_read.html")
Теперь необходимо создать шаблон:
vim myapp/templates/main/db_read.html
Вот его текст:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
lang="en">
<ul>
<li py:for="item in c.all_users">${item.id}:${item.name}</li>
</ul>
</html>
Теперь открываем страницу: http://127.0.0.1/main/db_read и любуемся нашим креативом =)
Итак, нам осталось разобраться с формами, пагинацией и все, можно будет приступать к созданию новых клевых сервисов =)
Pylons: обработка GET/POST параметров
Итак, продолжим наполнять жизнью наш веб аппликейшен. Сейчас будем обрабатывать GET и POST параметры, передаваемые нашим контроллерам (для этого используется объект responce.params причем, GET и POST ключи собираются в один словарь для удобства). Это довольно легко, добавляем в файл
ещё один метод:
И теперь открываем http://127.0.0.1/main/show_params?my_param=value555 и видим, что параметр передался в тело веб-страницы :)
vi myapp/controllers/main.py
ещё один метод:
def show_params(self):
return request.params['my_param']
И теперь открываем http://127.0.0.1/main/show_params?my_param=value555 и видим, что параметр передался в тело веб-страницы :)
Pylons: работа с сессиями
Итак, продолжим мучать Pylons :) Сейчас нам для полного веб-счастья не хватает возможности временно сохранять данные между запросами пользователей, для этой цели мы будем использовать сессии (в Pylons они предоставяются компонентом Beaker).
Для тестов добавим в код файла
Тут все довольно тривиально, за исключением строки "session.save()", в Pylons необходимо явно указывать, что изменения в сессии требуется сохранить, для этого и вызывается метод save().
Ну и еще - краткое описание внутренностей работы сессий. В cookie пользователю помещается переменная с именем веб-приложения (myapp) со значением "e18f7176b0832b030a5df1041b6ffb877d5377e11e93e0e7e783584523192c65e946fafd", что представляет собой хеш код, по которому производится идентификация владельца сессии. Время жизни сессии - до закрытия браузера.
Ну вот и все, теперь при каждом обновлении страницы http://127.0.0.1/main/count число будет увеличиваться.
Для тестов добавим в код файла
vi myapp/controllers/main.pyновый метод, count, который будет считать число открытий страницы для данного юзера:
def count(self):
if session.has_key('users_count'):
session['users_count'] = session['users_count'] + 1
else:
session['users_count'] = 0
session.save()
return "Users count: ", session['users_count']
Тут все довольно тривиально, за исключением строки "session.save()", в Pylons необходимо явно указывать, что изменения в сессии требуется сохранить, для этого и вызывается метод save().
Ну и еще - краткое описание внутренностей работы сессий. В cookie пользователю помещается переменная с именем веб-приложения (myapp) со значением "e18f7176b0832b030a5df1041b6ffb877d5377e11e93e0e7e783584523192c65e946fafd", что представляет собой хеш код, по которому производится идентификация владельца сессии. Время жизни сессии - до закрытия браузера.
Ну вот и все, теперь при каждом обновлении страницы http://127.0.0.1/main/count число будет увеличиваться.
Pylons: передача переменных из контроллера в шаблон
После того, как мы освоились с шаблонами пришло самое время научиться передавать переменные в шаблон, вещь ради которой все и затевалось. Открываем контроллер
и перед return добавляем строку
Теперь надо в шаблоне
отобразить содержимое переменной: удаляем строку "Hello World from Template!" и вносим в него следующий код между тегов html: ${c.welcome_text}
Теперь перезапускаем приложение и любуемся переданным в шаблон текстом :)
vi myapp/controllers/main.py
и перед return добавляем строку
c.welcome_text = "Hello World from Variable!"
Теперь надо в шаблоне
vi myapp/templates/main/index.html
отобразить содержимое переменной: удаляем строку "Hello World from Template!" и вносим в него следующий код между тегов html: ${c.welcome_text}
Теперь перезапускаем приложение и любуемся переданным в шаблон текстом :)
Pylons: работа с шаблонами
Теперь попробуем заменить наш вбитый в код контроллера текст на шаблон, для этого делаем следующее.
Создаем папку для шаблонов данного контроллера:
Создаем сам шаблон:
Обращаю внимание, что шаблон не является обычным текстом, это xml документ с определенной структурой. Пример содержимого файла вот такой:
Теперь открываем контроллер:
и заменяем
Теперь запускаем:
Подробная документация по синтаксису шаблонов: http://genshi.edgewall.org/wiki/Documentation/0.5.x/xml-templates.html
Создаем папку для шаблонов данного контроллера:
mkdir myapp/templates/main
Создаем сам шаблон:
vim myapp/templates/main/index.html
Обращаю внимание, что шаблон не является обычным текстом, это xml документ с определенной структурой. Пример содержимого файла вот такой:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/" lang="en">
Hello World from Template!
</html>
Теперь открываем контроллер:
vi myapp/controllers/main.py
и заменяем
return 'Hello World'на:
return render("main/index.html")
Теперь запускаем:
paster serve development.iniи наблюдаем, что шаблон считался из файла (текст "Hello World from Template!" вместо "Hello World!"), а не из кода контроллера, что позволяет разделить разработку логики от разработки визуальной части.
Подробная документация по синтаксису шаблонов: http://genshi.edgewall.org/wiki/Documentation/0.5.x/xml-templates.html
воскресенье, 18 октября 2009 г.
Pylons: создание первого контроллера
Итак, продолжим. Pylons на индексной странице сейчас показывает нам свой стандартный информер, что ну никак не вариант для реального приложения.
Создаем свой контроллер:
В результате этого действа будет создан файл: myapp/controllers/main.py, в котором будет один единственный класс (MainController) с одним методом, который покажет нам надпись "Hello world". Также будет создан файл myapp/tests/functional/test_main.py с тестами для данного контроллера, но они нам сейчас не нужны.
Перезапускаем приложение:
Теперь нам надо, чтобы эта страничка показывалась по адресу: http://127.0.0.1 Для этого открываем файл раутов (где производится настройка того, какой путь какой контроллер обрабатывает):
И в после строки "# CUSTOM ROUTES HERE" добавляем:
Все, стандартный контроллер подключен как индексная страница и по адресу http://127.0.0.1 отображается веселое "Hello world!" :)
Создаем свой контроллер:
paster controller main
В результате этого действа будет создан файл: myapp/controllers/main.py, в котором будет один единственный класс (MainController) с одним методом, который покажет нам надпись "Hello world". Также будет создан файл myapp/tests/functional/test_main.py с тестами для данного контроллера, но они нам сейчас не нужны.
Перезапускаем приложение:
paster serve --reload development.iniи открываем адрес: http://127.0.0.1/main/index
Теперь нам надо, чтобы эта страничка показывалась по адресу: http://127.0.0.1 Для этого открываем файл раутов (где производится настройка того, какой путь какой контроллер обрабатывает):
vi myapp/config/routing.py
И в после строки "# CUSTOM ROUTES HERE" добавляем:
map.connect('/', controller='main', action='index')и сносим файл шаблона (иначе не будет рабтать новый раут):
rm myapp/public/index.html
Все, стандартный контроллер подключен как индексная страница и по адресу http://127.0.0.1 отображается веселое "Hello world!" :)
Литература по Pylons
Вот суперская книга в открытом доступе: http://pylonsbook.com/
Перед полным погружением рекомендую прочесть: http://wiki.pylonshq.com/display/pylonsfaq/Home
Кукбук: http://wiki.pylonshq.com/display/pylonscookbook/Home
Очень хороший мануал: http://developer.co.ua/posts/view/pylons_python-frejmvork
Перед полным погружением рекомендую прочесть: http://wiki.pylonshq.com/display/pylonsfaq/Home
Кукбук: http://wiki.pylonshq.com/display/pylonscookbook/Home
Очень хороший мануал: http://developer.co.ua/posts/view/pylons_python-frejmvork
Подписаться на:
Сообщения
(
Atom
)