Учебники

Turbogears — Краткое руководство

TurboGears — Обзор

Web Application Framework или просто Web Framework представляет собой набор библиотек и модулей, который позволяет разработчику веб-приложений писать приложения, не заботясь о деталях низкого уровня, таких как протоколы, управление потоками и т. Д.

Веб-фреймворки

Что такое TurboGears?

TurboGears — это фреймворк для веб-приложений, написанный на Python. Первоначально созданная Kevin Dangoor в 2005 году, ее последняя версия TurboGears (версия 2.3.7) управляется группой разработчиков во главе с Марком Раммом и Флораном Аиде.

TurboGears следует парадигме Model-View-Controller, как и большинство современных веб-фреймворков, таких как Rails, Django, Struts и т. Д.

Контроллер модельного вида

MVC — это шаблон проектирования программного обеспечения для разработки веб-приложений. Модель контроллера представления модели состоит из трех частей:

  • Модель — самый низкий уровень шаблона отвечает за ведение данных.

  • Просмотр — это ответственность за отображение всех или части данных для пользователя.

  • Контроллер — программный код, который контролирует взаимодействие между моделью и представлением.

Модель — самый низкий уровень шаблона отвечает за ведение данных.

Просмотр — это ответственность за отображение всех или части данных для пользователя.

Контроллер — программный код, который контролирует взаимодействие между моделью и представлением.

MVC популярен, поскольку он изолирует логику приложения от уровня пользовательского интерфейса и поддерживает разделение задач. Здесь Контроллер получает все запросы для приложения и затем работает с Моделью, чтобы подготовить любые данные, необходимые для Представления. Затем представление использует данные, подготовленные контроллером, для генерации окончательного презентабельного ответа. Абстракция MVC может быть графически представлена ​​следующим образом:

MVC

Модель

Модель отвечает за управление данными приложения. Он отвечает на запрос от представления и также отвечает на инструкции от контроллера, чтобы обновить себя.

Вид

Представление данных в определенном формате, инициированное решением контроллера о представлении данных. Это основанные на сценариях системы шаблонов, которые очень легко интегрировать с технологией AJAX.

Контроллер

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

TurboGears построен на основе ряда библиотек и инструментов. Эти инструменты были изменены в разных версиях TurboGears. Компоненты текущей версии (версия 2.3.7) перечислены ниже.

SQLAlchemy

Это набор SQL с открытым исходным кодом, который обеспечивает сопоставление отношений объектов (ORM) для кода Python.

SQLAlchemy

Genshi

Этот шаблонизатор используется для создания внешнего интерфейса приложений TG. Система веб-шаблонов объединяет шаблон с определенным источником данных для отображения динамических веб-страниц.

ToscaWidgets

Это библиотека виджетов для генерации HTML-форм с серверными элементами управления. Tosca также выступает в качестве промежуточного программного обеспечения для связи с виджетами JavaScript и наборами инструментов.

коробка передач

Он предоставляет набор команд для управления проектами и серверными приложениями TurboGears. Приложения TurboGears могут быть развернуты на любом веб-сервере, совместимом с WSGI.

Интерфейс шлюза веб-сервера (WSGI) был принят в качестве стандарта для разработки веб-приложений на Python. WSGI — это спецификация универсального интерфейса между веб-сервером и веб-приложениями. Пакет wsgiref является эталонной реализацией WSGI. Он используется для добавления поддержки WSGI в веб-фреймворк TurboGears. Модуль simple_server в этом пакете реализует простой HTTP-сервер, который обслуживает приложения WSGI. Мы будем использовать его для тестирования приложений, разработанных в этом уроке.

TurboGears — Окружающая среда

необходимое условие

Python 2.6 или выше. Более ранние версии TurboGears не были совместимы с Python 3.X. Последняя версия утверждает, что хорошо работает на Python 3.X. Однако официальная документация TurboGears по-прежнему основана на среде Python 2.7.

Следующая команда устанавливает virtualenv

pip install virtualenv

Эта команда нуждается в правах администратора . Добавьте sudo перед pip в Linux / Mac OS. Если вы работаете в Windows, войдите как Администратор. На Ubuntu virtualenv может быть установлен с помощью менеджера пакетов.

Sudo apt-get install virtualenv

После установки новая виртуальная среда создается в папке.

mkdir newproj
cd newproj
virtualenv venv

Чтобы активировать соответствующую среду, в Linux / OS X

venv/bin/activate

в Windows

venv\scripts\activate

Теперь мы готовы установить TurboGears в этой среде. Минимальная установка TurboGears выполняется с помощью следующей команды —

pip install TurboGears2

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

Чтобы установить TurboGears вместе со средствами разработки, используйте следующую команду —

pip install tg.devtools

TurboGears — Первая программа

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

Класс приложения в приложении TG наследуется от класса TGController . Методы в этом классе доступны для доступа @expose декоратором из модуля tg . В нашем первом приложении метод index () отображается как корень нашего приложения. Класс TGController также необходимо импортировать из модуля tg .

from tg import expose, TGController
class MyController(TGController):
   @expose()
   def index(self):
      return 'Hello World turbogears'

Затем установите конфигурацию приложения и объявите объект приложения. Здесь конструктор класса AppConfig принимает два параметра — минимальный атрибут со значением true и класс контроллера.

config = AppConfig(minimal = True, root_controller = RootController())
application = config.make_wsgi_app()

Функция make_wsgi_app () здесь создает объект приложения.

Чтобы обслуживать это приложение, нам нужно запустить HTTP-сервер. Как упоминалось ранее, мы будем использовать модуль simple_server в пакете wsgiref для его настройки и запуска. Этот модуль имеет метод make_server (), который требует номер порта и объект приложения в качестве аргументов.

from wsgiref.simple_server import make_server
server = make_server('', 8080, application)
server.serve_forever()

Это означает, что наше приложение будет обслуживаться через порт 8080 локального хоста.

Ниже приведен полный код нашего первого приложения TurboGears —

app.py

from wsgiref.simple_server import make_server
from tg import expose, TGController, AppConfig

class MyController(TGController):

   @expose()
   def index(self):
      return 'Hello World TurboGears'
		 
config = AppConfig(minimal = True, root_controller = MyController())
application = config.make_wsgi_app()

print "Serving on port 8080..."
server = make_server('', 8080, application)
server.serve_forever()

Запустите приведенный выше скрипт из оболочки Python.

Python app.py

Введите http: // localhost: 8080 в адресной строке браузера, чтобы просмотреть сообщение «Hello World TurboGears».

В tg.devtools TurboGears есть коробка передач. Это набор команд, которые полезны для управления более сложными проектами TG. Проекты с полным стеком можно быстро создать с помощью следующей команды Gearbox —

gearbox quickstart HelloWorld

Это создаст проект под названием HelloWorld .

TurboGears — Зависимости

Проект TurboGears содержит следующие каталоги —

  • Конфиг — Где находится настройка проекта и конфигурация

  • Контроллеры — все контроллеры проекта, логика веб-приложения

  • i018n — файлы переводов для поддерживаемых языков

  • Lib — служебные функции и классы Python

  • Модель — База данных моделей

  • Общедоступные статические файлы — CSS, JavaScript и изображения

  • Шаблоны — Шаблоны, предоставляемые нашими контролерами.

  • Тесты — набор тестов сделано.

  • Websetup — функции, выполняемые при настройке приложения.

Конфиг — Где находится настройка проекта и конфигурация

Контроллеры — все контроллеры проекта, логика веб-приложения

i018n — файлы переводов для поддерживаемых языков

Lib — служебные функции и классы Python

Модель — База данных моделей

Общедоступные статические файлы — CSS, JavaScript и изображения

Шаблоны — Шаблоны, предоставляемые нашими контролерами.

Тесты — набор тестов сделано.

Websetup — функции, выполняемые при настройке приложения.

Как установить проект

Этот проект теперь должен быть установлен. Файл setup.py уже предоставлен в базовом каталоге проекта. Зависимости проекта устанавливаются при выполнении этого скрипта.

Python setup.py develop

По умолчанию следующие зависимости устанавливаются во время настройки проекта:

  • мензурка
  • Genshi
  • zope.sqlalchemy
  • SQLAlchemy
  • перегонный куб
  • repoze.who
  • tw2.forms
  • tgext.admin ≥ 0.6.1
  • WebHelpers2
  • галдеж

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

Gearbox serve –reload –debug

Следуйте вышеупомянутой команде, чтобы служить готовым примером проекта. Откройте http: // localhost: 8080 в браузере. Этот готовый пример приложения дает краткое представление о самой платформе TurboGears.

Окно проекта

В этом проекте Hello контроллер по умолчанию создается в каталоге контроллеров как Hello / hello / controllers.root.py . Давайте изменим root.py с помощью следующего кода —

from hello.lib.base import BaseController
from tg import expose, flash

class RootController(BaseController):
   movie = MovieController()
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
		
   @expose()
   def _default(self, *args, **kw):
      return "This page is not ready"

Когда основное рабочее приложение готово, в класс контроллера можно добавить больше представлений. В приведенном выше классе Mycontroller добавлен новый метод sayHello () . Декоратор @expose () присоединяет к нему URL-адрес / sayHello . Эта функция предназначена для принятия имени в качестве параметра из URL.

После запуска сервера с помощью команды «gearbox serve» http: // localhost: 8080 . Сообщение Hello World будет отображаться в браузере, даже если введены следующие URL —

HTTP: // локальный: 8080 /

HTTP: // локальный: 8080 / индекс

Все эти URL-адреса сопоставлены с методом RootController.index () . Этот класс также имеет метод _default (), который будет вызываться всякий раз, когда URL-адрес не сопоставлен с какой-либо конкретной функцией. Ответ на URL отображается на функцию декоратором @expose ().

С помощью URL можно отправить параметр в открытую функцию. Следующая функция читает параметр имени из URL.

@expose()
def sayHello(self, name):
   return '<h3>Hello %s</h3>' %name

Следующий вывод будет отображаться в браузере как ответ на URL — http: // localhost: 8080 /? Name = MVL

Hello MVL

TurboGears автоматически сопоставляет параметры URL с аргументами функции. Наш класс RootController унаследован от BaseController. Это определяется как base.py в папке lib приложения.

Его код следующий:

from tg import TGController, tmpl_context
from tg import request

__all__ = ['BaseController']

def __call__(self, environ, context):
   tmpl_context.identity = request.identity
   return TGController.__call__(self, environ, context)

TGController .__ call__ отправляет методу Controller, на который направляется запрос.

TurboGears — Шаблоны обслуживания

Событие, хотя HTML-содержимое может быть возвращено в браузер, для более сложного вывода всегда предпочтительнее использовать механизм шаблонов. В полномасштабном проекте, «быстро запущенном» с помощью коробки передач, Genshi включен как средство визуализации шаблонов по умолчанию. Однако в минимальном приложении необходимо установить и включить Genshi (или любой другой шаблонизатор, например, jinja). Механизм шаблонов Genshi позволяет писать шаблоны в чистом формате xhtml и проверяет их, чтобы обнаружить проблемы во время компиляции и предотвратить обслуживание неработающих страниц.

На шаблоны ссылаются с помощью точечной нотации. В нашем проекте Hello имеется каталог шаблонов для хранения веб-страниц шаблонов. Следовательно, sample.html будет называться hello.templates.sample (расширение не указано). TurboGears визуализирует этот шаблон через декоратор экспозиции, чтобы связать с ним метод контроллера с помощью функции tg.render_template () .

Открытая функция контроллера возвращает объект словаря Python. Этот объект словаря в свою очередь передается связанному шаблону. Заполнители в шаблоне заполняются значениями словаря.

Для начала давайте отобразим веб-страницу с простым HTML-скриптом. Открытый контроллер возвращает пустой словарный объект, поскольку мы не собираемся отправлять какие-либо данные для анализа в HTML-сценарии.

Как создать образец HTML

Наш sample.html приведен ниже. Убедитесь, что он хранится в каталоге шаблонов проекта.

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
   </body>
</html>

Добавьте функцию sample () в root.py и выставьте через нее sample.html.

@expose("hello.templates.sample")
   def sample(self):
      return {}

Следующий результат будет отображаться в браузере при вводе URL-адреса http: // localhost: 8080 / sample после запуска веб-сервера.

Показать результат

Как уже упоминалось выше, объект словаря отправляется в виде набора параметров в шаблон Genshi. Этот шаблон содержит «заполнители», которые динамически заполняются параметрами, полученными от контроллера.

Давайте изменим функцию sample () для отправки объекта словаря в шаблон примера.

@expose("hello.templates.sample")
   def sample(self,name):
      mydata = {'person':name}
      return mydata

Создайте sample.html в папке с шаблонами ( templates \ sample.html )

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, my name is ${person}!.</h2>
   </body>
</html>

В приведенном выше HTML-коде $ {person} является заполнителем. Введите http: // localhost: 8080 / sample? Name = MVL в качестве URL-адреса в браузере. Этот URL-адрес сопоставлен с методом sample () в нашем корневом контроллере. Возвращает объект словаря. Это выбирается связанной страницей шаблона sample.html в каталоге шаблонов. Затем $ {person} заменяется MVL на веб-странице.

Также возможно получить доступ к данным формы HTML в функции контроллера. Форма HTML использует для отправки данных формы.

Результат

TurboGears — методы HTTP

Протокол Http является основой передачи данных во всемирной паутине. В этом протоколе определены различные методы извлечения данных из указанного URL. В следующей таблице приведены различные методы http —

Sr.No. Методы и описание HTTP
1

ПОЛУЧИТЬ

Отправляет данные в незашифрованном виде на сервер. Самый распространенный метод.

2

ГОЛОВА

То же, что GET, но без тела ответа

3

СООБЩЕНИЕ

Используется для отправки данных формы HTML на сервер. Данные, полученные методом POST, не кэшируются сервером.

4

ПОЛОЖИЛ

Заменяет все текущие представления целевого ресурса на загруженный контент.

5

УДАЛЯТЬ

Удаляет все текущие представления целевого ресурса, заданного URL

ПОЛУЧИТЬ

Отправляет данные в незашифрованном виде на сервер. Самый распространенный метод.

ГОЛОВА

То же, что GET, но без тела ответа

СООБЩЕНИЕ

Используется для отправки данных формы HTML на сервер. Данные, полученные методом POST, не кэшируются сервером.

ПОЛОЖИЛ

Заменяет все текущие представления целевого ресурса на загруженный контент.

УДАЛЯТЬ

Удаляет все текущие представления целевого ресурса, заданного URL

Создание формы HTML

Давайте создадим форму HTML и отправим данные формы на URL. Сохраните следующий скрипт как login.html

<html>
   <body>
      <form action = "http://localhost:8080/login" method = "get">
         <p>Enter Name:</p>
         <p><input type = "text" name = "nm" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
   </body>
</html>

Данные, введенные в этой форме, должны быть отправлены на URL / login . Теперь создайте функцию контроллера loginpage () и откройте для него вышеуказанную html-страницу.

@expose("hello.templates.login")
   def loginpage(self):
      return {}

Чтобы получить данные формы, предоставьте контроллер login () , который имеет атрибуты формы в качестве своих параметров. Здесь «nm» — имя поля ввода текста в форме входа в систему, то же самое используется в качестве параметра функции login ().

@expose("hello.templates.sample")
   def login(self, nm):
      name = nm
      return {'person':name}

Как видно, данные, полученные из формы входа, отправляются в шаблон sample.html (использовался ранее). Он анализируется механизмом шаблонов Genshi для генерации следующего вывода:

Генши Результат

Метод POST

Когда форма HTML использует метод POST для отправки данных на URL-адрес в атрибуте действия, данные формы не отображаются в URL-адресе. Закодированные данные принимаются в качестве аргумента dict функцией контроллера. Аргумент ** kw ниже — это объект словаря, содержащий данные.

HTML-форма содержит два поля ввода текста.

<html>
   <body>
	
      <form action = "http://localhost:8080/marks" method = "post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
		
   </body>	
</html>

Контроллер marks () получает данные формы и отправляет их в шаблон sample.html . Код для root.py выглядит следующим образом —

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
   def marksform(self):
      return {}
		
   @expose("hello.templates.sample")
   def marks(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      ttl = int(phy)+int(maths)
      mydata = {'phy':phy, 'maths':maths, 'total':ttl}
      return mydata

Наконец, шаблон sample.html выглядит следующим образом:

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
      <h3>Marks in Physics: ${phy}.</h3>
      <h3>Marks in Maths: ${maths}.</h3>
      <h3>Total Marks: ${total}</h3>
   </body>
	
</html>

Запустите сервер (если он еще не запущен)

Gearbox server –reload –debug

Введите http: // localhost :: 8080 / marksform в браузере

Образец шаблона

Sample.html отобразит следующий вывод —

Пример HTML-результата

TurboGears — Genshi Template Language

Genshi — это язык шаблонов на основе XML. Он похож на Kid , который раньше был движком шаблонов для более ранних версий TurboGears. Genshi и Kid вдохновлены другими известными языками шаблонов, такими как HSLT, TAL и PHP .

Шаблон Genshi состоит из директив обработки. Эти директивы являются элементами и атрибутами в шаблоне. Директивы Genshi определены в пространстве имен http://genshi.edgewall.org/ . Следовательно, это пространство имен должно быть объявлено в корневом элементе шаблона.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
...
</html>

Объявление выше означает, что пространство имен по умолчанию установлено в XHTML, а директивы Genshi имеют префикс «py».

Директивы Генши

Ряд директив определен в Genshi. Следующий список перечисляет директивы Genshi —

  • ру: если
  • ру: выбрать
  • ру: для
  • р: Защита
  • ру: матч
  • ру: с
  • ру: заменить
  • ру: содержание
  • ру: ATTRS
  • ру: полоса

Условные разделы

Genshi предоставляет две директивы для условного рендеринга контента — py: if и py: select.

ру: если

Содержимое элемента этой директивы будет отображено, только если выражение в условии if оценивается как true. Предполагая, что данные в контексте шаблона: {‘foo’: True, ‘bar’: ‘Hello’} , следующая директива —

<div>
   <b py:if = "foo">${bar}</b>
</div>

приведет к

Hello

Однако этот вывод не будет отображаться, если для ‘foo’ установлено значение False .

Эта директива также может быть использована в качестве элемента. В этом случае <py: if> должен быть закрыт соответствующим </ py: if>

<div>
   <py:if test = "foo">
      <b>${bar}</b>
   </py:if>
</div>

ру: выбрать

Расширенная условная обработка возможна с использованием py: выбрать в сочетании с директивами py: when и py: else. Эта функция похожа на конструкцию switch-case в C / C ++ .

Выражение в py: директива Choose проверяется с различными значениями, идентифицированными с py: когда будут отображаться альтернативы и соответствующее содержимое. Альтернатива по умолчанию может быть предоставлена ​​в форме директивы py: else.

<div py:choose = "foo”>
   <span py:when = "0">0</span>
   <span py:when = "1">1</span>
   <span py:otherwise = "">2</span>
</div>

Следующий пример иллюстрирует использование py: choose и py: when директив. HTML-форма отправляет данные на / mark URL. Функция marks () перенаправляет метки и результаты в виде объекта словаря в шаблон total.html . Условное отображение результата Pass / Fail достигается использованием директив py: choose и py: when .

HTML-скрипт ввода отметок ( marks.html ) выглядит следующим образом:

<html>
   <body>
      <form action = "http://localhost:8080/marks" method = "post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
   </body>
</html>

Полный код root.py выглядит следующим образом. Контроллер marks () отправляет оценки и результат в шаблон total.html

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
      def marksform(self):
      return {}
		
   @expose("hello.templates.total")
      def marks(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      ttl = int(phy)+int(maths)
      avg = ttl/2
		
      if avg ≥ 50:
         mydata = {'phy':phy, 'maths':maths, 'total':ttl, 'result':2}
      else:
         mydata = {'phy':phy, 'maths':maths, 'total':ttl,'result':1}
	
      return mydata

Total.html в папке шаблонов получает данные словаря и условно анализирует их в выводе html следующим образом:

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
      <h3>Marks in Physics: ${phy}.</h3>
      <h3>Marks in Maths: ${maths}.</h3>
      <h3>Total Marks: ${total}</h3>
		
      <div py:choose = "result">
         <span py:when = "1"><h2>Result: Fail</h2></span>
         <span py:when = "2"><h2>Result: Pass</h2></span>
      </div>
		
   </body>
</html>

Запустите сервер (если он еще не запущен)

Gearbox server –reload –debug

Введите http: // localhost :: 8080 / marksform в браузере —

Окно результатов

Total.html будет отображать следующий вывод —

Всего HTML

ру: для

Элемент в директиве py: for повторяется для каждого элемента итерируемого объекта, обычно объекта списка Python. Если items = [1,2,3] присутствует в контексте шаблона, его можно повторить с помощью следующей py: for директива —

<ul>
   <li py:for = "item in items">${item}</li>
</ul>

Будет получен следующий вывод —

1
2
3

В следующем примере показаны данные формы HTML, представленные в шаблоне total.html с использованием директивы py: for, также можно использовать следующим образом:

<py:for each = "item in items">
   <li>${item}</li>
</py:for>

HTML Form Script

<html>
   <body>
	
      <form action = "http://localhost:8080/loop" method="post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Chemistry:</p>
         <p><input type = "text" name = "che" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
		
   </body>
</html>

Контроллер loop () считывает данные формы и отправляет их в total.template в форме объекта списка.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
   def marksform(self):
   return {}
	
   @expose("hello.templates.temp")
   def loop(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      che = kw['che']
      l1 = []
      l1.append(phy)
      l1.append(che)
      l1.append(maths)
		
   return ({'subjects':['physics', 'Chemistry', 'Mathematics'], 'marks':l1})

Шаблон temp.html использует цикл py: for для отображения содержимого объекта dict в форме таблицы.

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/" lang = "en">
	
   <body>
      <b>Marks Statement</b>
      <table border = '1'>
         <thead>
            <py:for each = "key in subjects"><th>${key}</th></py:for>
         </thead>
         <tr>
            <py:for each = "key in marks"><td>${key}</td></py:for>
         </tr>
      </table>
   </body>
</html>

Запустите сервер (если он еще не запущен)

gearbox server –reload –debug

Введите http: // localhost :: 8080 / marksform в браузере.

Окно Результат

При отправке вышеуказанной формы в браузере будет отображаться следующий вывод.

Форма вывода

р: Защита

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

Директива py: def имеет следующий синтаксис:

<p py:def = "greeting(name)">
   Hello, ${name}!
</p>

Этот макрос может быть представлен с помощью значения переменной параметра name.

${greeting('world')}
${greeting('everybody)}

Эта директива также может использоваться с другой версией синтаксиса следующим образом:

<py:def function = "greeting(name)">
   <p>Hello, ${name}! </p>
</py:def>

В следующем примере контроллер macro () в root.py отправляет объект dict с двумя ключами name1 и name2 в шаблон macro.html.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.macro')
   def macro(self):
      return {'name1':'TutorialPoint', 'name2':'TurboGears'}

Этот шаблон macro.html содержит определение макроса, называемого приветствием. Он используется для генерации приветственного сообщения для данных, полученных от контроллера.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <body>
      <h2>py:def example</h2>
		
      <div>
         <div py:def = "greeting(name)">
            Hello, Welcome to ${name}!
         </div>
				
         <b>
            ${greeting(name1)}
            ${greeting(name2)}
         </b>
			
      </div>
   </body>
</html>

Запустите сервер, используя коробку передач

gearbox serve –reload –debug

Вызовите контроллер macro (), введя следующий URL в браузере —

HTTP: // локальный: 8080 / макро

Следующий вывод будет отображен в браузере —

Пример Def

ру: с

Эта директива позволяет вам присваивать выражения локальным переменным. Эти локальные переменные делают выражение внутри менее многословным и более эффективным.

Предполагая, что x = 50 задано в данных контекста для шаблона, следующая будет py: with директива —

<div>
   <span py:with = "y = 50; z = x+y">$x $y $z</span>
</div>

Это приведет к следующему выводу —

50 50 100

Также доступна альтернативная версия для py: with —

<div>
   <py:with = "y = 50; z = x+y">$x $y $z</py:with>
</div>

В следующем примере контроллер macro () возвращает объект dict с ключами name, phy и maths.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.macro')
   def macro(self):
      return {'name':'XYZ', 'phy':60, 'maths':70}

Шаблон macro.html добавляет значения ключей phy и maths с помощью директивы py: with.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <body>
      <h2>py:with example</h2>
      <h3>Marks Statement for : ${name}!</h3>
		
      <b>Phy: $phy Maths: $maths
         <span py:with = "ttl = phy+maths">Total: $ttl</span>
      </b>
		
   </body>
	
</html>

Браузер отобразит следующий вывод в ответ на URL http: // localhost: 8080 / macro

Py: например

Директивы по манипулированию структурой

Директива py: attrs добавляет, изменяет или удаляет атрибуты элемента.

<ul>
   <li py:attrs = "foo">Bar</li>
</ul>

Если foo = {‘class’: ‘collapse’} присутствует в контексте шаблона, который будет представлен вышеупомянутым фрагментом.

<ul>
   <li class = "collapse">Bar</li>
</ul>

Директива py: content заменяет любой вложенный контент результатом вычисления выражения —

<ul>
   <li py:content = "bar">Hello</li>
</ul>

Если в контекстных данных указать bar = ‘Bye’, это приведет к

<ul>
   <li>Bye</li>
</ul>

Директива py: replace заменяет сам элемент на результат вычисления выражения —

<div>
   <span py:replace = "bar">Hello</span>
</div>

Если в контекстных данных задано значение bar = ‘Bye’,

<div>
   Bye
</div>

TurboGears — Включает

Содержимое другого XML-документа (особенно HTML-документа) можно включить с помощью тегов включения в текущем документе. Чтобы включить такое включение, пространство имен XInclude должно быть объявлено в корневом элементе HTML-документа.

<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:xi = "http://www.w3.org/2001/XInclude >

Приведенное выше объявление указывает, что директива include содержит префикс «xi» . Чтобы добавить содержимое другой html-страницы в текущий документ, используйте директиву xi: include следующим образом:

<xi:include href = "somepage.html" />

В следующем примере root.py содержит контроллер include (), который предоставляет include.html.

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.include')
   def include(self):
      return {}

HTML заголовка и нижнего колонтитула

В include.html объявлено пространство имен include и добавлено содержимое heading.html и footer.html. Вот HTML-скрипт шаблонов \ include.html —

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:xi = "http://www.w3.org/2001/XInclude">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <xi:include href = "heading.html" />
      <h2>main content </h2>
      <xi:include href = "footer.html" />
   </body>
	
</html>

Вот код шаблонов \ heading.html —

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h1>This is page Header</h1>
   </body>
</html>

Ниже приведены шаблоны \ footer.html

<html>
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h3>This is page footer</h3>
   </body>
</html>

Запустите разработку с помощью редуктора и введите http: // localhost: 8080 / include в браузере. Вывод будет выглядеть так, как показано ниже —

Примеры шаблонов

Таким образом, модульная конструкция видов может быть достигнута. Если ресурс, упомянутый в директиве xi: include, недоступен, возникнет ошибка. В таком случае альтернативный ресурс может быть загружен с использованием xi: fallback.

<xi:include href = “main.html”>
   <xi:fallback href = ”default.html”/>
</xi.include>

Включение содержимого может быть сделано динамическим как атрибут href, который может содержать выражения.

Добавьте следующий контроллер в root.py.

@expose('hello.templates.ref-include')
   def refinclude(self):
      return {'pages':['heading','main','footer']}

Сохраните следующий код как ref-include.html в папке шаблонов.

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   xmlns:xi = "http://www.w3.org/2001/XInclude">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <xi:include href = "${name}.html" py:for = "name in pages" />
   </body>
	
</html>

Перед запуском сервера убедитесь, что в папке templates находятся heading.html, main.html и footer.html. Введите http: // localhost: 8082 / refinclude в браузере, чтобы получить следующий вывод

Шаблон нижнего колонтитула

TurboGears — рендеринг JSON

Декоратор @expose () по умолчанию отображает HTML-контент. Однако это может быть установлено в тип контента json . TurboGears поддерживает рендеринг json с помощью класса tg.jsonify.JSONEncoder ( ** kwargs ) . Для рендеринга данных json просто передайте json как тип контента, чтобы выставить декоратор.

@expose('json')
def jsondata(self, **kwargs):
   return dict(hello = 'World')

Если в браузере введен URL ‘/ jsondata’, он ответит, показывая —

{"hello": "World"}

рендеринг jsonp

JSONP означает JSON с отступом. Он работает аналогично выводу json, за исключением того факта, что он предоставляет ответ application / javascript с вызовом функции javascript, предоставляющей все значения, возвращаемые контроллером в качестве аргументов функции.

Чтобы включить рендеринг jsonp, вы должны сначала добавить его в список необходимых движков внутри вашего приложения — config / app_cfg.py

base_config.renderers.append('jsonp')

Напишите ваш выставленный декоратор следующим образом —

@expose('json')
@expose('jsonp')
def jsonpdata (self, **kwargs): 
   return dict(hello = 'World')

При доступе к / jsonpdata? Callback = callme вы должны увидеть —

callme({"hello": "World"});

TurboGears — иерархия URL

Иногда веб-приложению может потребоваться структура URL, имеющая более одного уровня. TurboGears может просматривать иерархию объектов, чтобы найти подходящий метод, который может обработать ваш запрос.

Проект, «быстро запущенный» с коробкой передач, имеет класс BaseController в папке lib проекта. Он доступен как «Hello / hello / lib / base.py». Он служит базовым классом для всех субконтроллеров. Чтобы добавить подуровень URL в приложение, спроектируйте подкласс BlogController, производный от BaseController.

Этот BlogController имеет две функции контроллера, index () и post (). Оба предназначены для представления шаблона каждый, blog.html и post.html.

Примечание. Эти шаблоны помещаются во вложенную папку — templates / blog

class BlogController(BaseController):

   @expose('hello.templates.blog.blog')
   def index(self):
      return {}
		
   @expose('hello.templates.blog.post')
   def post(self):
      from datetime import date
      now = date.today().strftime("%d-%m-%y")
      return {'date':now}

Теперь объявите объект этого класса в классе RootController (в root.py) следующим образом:

class RootController(BaseController):
   blog = BlogController()

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

Когда введен URL-адрес http: // localhost: 8080 / blog / , он будет сопоставлен с функцией контроллера index () внутри класса BlogController. Аналогично, http: // localhost: 8080 / blog / post вызовет функцию post ().

Код для blog.html и post.html приведен ниже.

Blog.html

<html>
   <body>
      <h2>My Blog</h2>
   </body>
</html>

post.html

<html>
   <body>
      <h2>My new post dated $date</h2>
   </body>
</html>

Когда введен URL http: // localhost: 8080 / blog / , он выдаст следующий вывод:

Блог

Когда введен URL http: // localhost: 8080 / blog / post , он выдаст следующий результат:

Сообщение блога

TurboGears — ToscaWidgets Forms

Одним из наиболее важных аспектов любого веб-приложения является представление пользовательского интерфейса для пользователя. HTML предоставляет тег <form>, который используется для разработки интерфейса. Элементы формы, такие как ввод текста, радио, выбор и т. Д. Могут быть использованы соответствующим образом. Данные, введенные пользователем, передаются в виде сообщения Http-запроса на серверный скрипт методом GET или POST.

Серверный скрипт должен воссоздавать элементы формы из данных http-запроса. Таким образом, в этом случае элементы формы должны быть определены дважды — один раз в HTML и снова в сценарии на стороне сервера.

Еще одним недостатком использования формы HTML является то, что трудно (если не невозможно) визуализировать элементы формы динамически. HTML сам по себе не позволяет проверять вводимые пользователем данные.

ToscaWidgets2

TurboGears использует ToscaWidgets2, гибкую библиотеку для рендеринга и проверки форм. Используя ToscaWidgets, мы можем определить поля формы в нашем скрипте Python и отобразить их, используя шаблон HTML. Также возможно применить проверку к полю tw2.

Библиотека ToscaWidgets представляет собой набор из множества модулей. Некоторые важные модули перечислены ниже —

  • tw2.core — обеспечивает базовую функциональность. Виджеты в этом модуле не предназначены для конечного пользователя.

  • tw2.forms — это базовая библиотека форм. Он содержит виджеты для полей, наборов полей и форм.

  • tw2.dynforms — содержит функциональность динамических форм.

  • tw2.sqla — это интерфейс для базы данных SQLAlchemy.

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

tw2.forms — это базовая библиотека форм. Он содержит виджеты для полей, наборов полей и форм.

tw2.dynforms — содержит функциональность динамических форм.

tw2.sqla — это интерфейс для базы данных SQLAlchemy.

tw2.forms

Он содержит класс Form, который служит основой для пользовательских форм. Существует класс TableForm, который полезен для визуализации полей в таблице с двумя столбцами. ListForm представляет свои поля в неупорядоченном списке.

Sr.No. Поля и описание
1

Текстовое поле

Однострочное поле ввода текста

2

TextArea

Многострочное поле ввода текста

3

CheckBox

Представлен прямоугольный флажок с надписью

4

CheckBoxList

Множественные флажки группы pf

5

Переключатель

Кнопка переключения для выбора / отмены выбора

6

RadioButtonList

Группа взаимоисключающих Радио кнопок

7

PasswordField

Аналогично текстовому полю, но клавиши ввода не отображаются

8

CalendarDatePicker

Позволяет пользователю выбрать дату

9

SubmitButton

Кнопка для отправки формы

10

ImageButton

Кликабельная кнопка с изображением сверху

11

SingleSelectField

Позволяет выбрать один элемент из списка

12

MultipleSelectField

Позволяет выбрать несколько элементов из списка

13

FileField

Поле для загрузки файла

14

EmailField

Поле ввода электронной почты

15

URLField

Поле ввода для ввода URL

16

NumberField

Спинбокс номер

17

RangeField

Ползунок номера

Текстовое поле

Однострочное поле ввода текста

TextArea

Многострочное поле ввода текста

CheckBox

Представлен прямоугольный флажок с надписью

CheckBoxList

Множественные флажки группы pf

Переключатель

Кнопка переключения для выбора / отмены выбора

RadioButtonList

Группа взаимоисключающих Радио кнопок

PasswordField

Аналогично текстовому полю, но клавиши ввода не отображаются

CalendarDatePicker

Позволяет пользователю выбрать дату

SubmitButton

Кнопка для отправки формы

ImageButton

Кликабельная кнопка с изображением сверху

SingleSelectField

Позволяет выбрать один элемент из списка

MultipleSelectField

Позволяет выбрать несколько элементов из списка

FileField

Поле для загрузки файла

EmailField

Поле ввода электронной почты

URLField

Поле ввода для ввода URL

NumberField

Спинбокс номер

RangeField

Ползунок номера

В следующем примере создается форма с использованием некоторых из этих виджетов. Хотя большинство этих виджетов определены в tw2.forms, CalendarDateField определен в модуле tw2.Dynforms. Следовательно, оба этих модуля вместе с tw2.core импортируются в начале —

import tw2.core as twc
import tw2.forms as twf
import tw2.dynforms as twd

Форма ToscaWidgets — это класс, производный от базового класса tw2.forms.form . Требуемые виджеты размещаются внутри объекта Layout. В этом примере используется TableLayout . Виджеты отображаются в виде таблицы с двумя столбцами. Первый столбец показывает заголовок, а второй столбец показывает поле ввода или выбора.

Объект TextField создается с использованием следующего конструктора —

twf.TextField(size, value = None)

Если не указано, объект TextField принимает размер по умолчанию и изначально пуст. При объявлении объекта TextArea можно указать количество строк и столбцов.

twf.TextArea("",rows = 5, cols = 30)

Объект NumberField — это TextField, который может принимать только цифры. Стрелки вверх и вниз генерируются на правой границе, чтобы увеличить или уменьшить число внутри нее. Начальное значение также может быть указано в качестве аргумента в конструкторе.

twf.NumberField(value)

Справа от поля CalendarDatePicker отображается кнопка календаря. При нажатии появляется селектор даты. Пользователь может вручную ввести дату в поле или выбрать из селектора даты.

twd.CalendarDatePicker()

Объект EmailField представляет TextField, но текст в нем должен быть в формате электронной почты.

EmailID = twf.EmailField()

Следующая форма также имеет RadioButtonList. Конструктор этого класса содержит объект List в качестве значения параметра options. Радиокнопка для каждого параметра будет отображаться. Выбор по умолчанию указывается параметром value.

twf.RadioButtonList(options = ["option1","option2"],value = option1)

CheckBoxList отображает флажки для каждой опции в списке.

twf.CheckBoxList(options = [option1, option2, option3])

В этой библиотеке ToscaWidgets раскрывающийся список называется полем SingleSelect. Элементы в объекте List, соответствующие параметру options, формируют выпадающий список. Видимый заголовок устанавливается как значение параметра prompt_text.

twf.SingleSelectField(prompt_text = 'text', options=['item1', 'item2', 'item3'])

По умолчанию в форме отображается кнопка «Отправить» с надписью «сохранить». Чтобы отобразить другой заголовок, создайте объект SubmitButton и укажите его в качестве параметра значения.

twf.SubmitButton(value = 'Submit')

Форма отправляется по URL-адресу, который указывается в качестве значения параметра действия формы. По умолчанию данные формы отправляются методом http POST.

action = 'URL'

В следующем коде форма с именем AdmissionForm разработана с использованием описанных выше виджетов. Добавьте этот код в root.py перед классом RootController.

class AdmissionForm(twf.Form):
   class child(twf.TableLayout):
      NameOfStudent = twf.TextField(size = 20)
      AddressForCorrespondance = twf.TextArea("", rows = 5, cols = 30)
      PINCODE = twf.NumberField(value = 431602)
      DateOfBirth = twd.CalendarDatePicker()
      EmailID = twf.EmailField()
      Gender = twf.RadioButtonList(options = ["Male","Female"],value = 'Male')
      Subjects = twf.CheckBoxList(options = ['TurboGears', 'Flask', 'Django', 'Pyramid'])

      MediumOfInstruction = twf.SingleSelectField(prompt_text = 'choose',
         options = ['English', 'Hindi', 'Marathi', 'Telugu'])
			
      action = '/save_form'
      submit = twf.SubmitButton(value ='Submit')

Теперь сохраните этот код ниже как twform.html в каталоге шаблонов —

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
   
   <head>
      <title>TurboGears Form Example</title>
   </head>
   
   <body>
      <div id = "tw form">
         ${form.display(value = dict(title = 'default title'))}
      </div>
   </body>
   
</html>

В классе RootController (в root.py) добавьте следующую функцию контроллера —

@expose('hello.templates.twform')
def twform(self, *args, **kw):
   return dict(page = 'twform', form = MovieForm)

В классе AdmissionForm мы указали / save_form как URL действия. Следовательно, добавьте функцию save_form () в RootController.

@expose()
def save_movie(self, **kw):
   return str(kw)

Убедитесь, что сервер работает (с помощью коробки передач). Введите http: // localhost: 8080 / twform в браузере.

формы

Нажатие кнопки « Отправить» отправит эти данные в URL save_form () , который отобразит данные формы в виде объекта словаря.

{
   'EmailID': u'lathkar@yahoo.com', 
   'NameOfStudent': u'Malhar Lathkar', 
   'Gender': u'Male', 
   'PINCODE': u'431602', 
   'DateOfBirth': u'2015-12-29', 
   'Subjects': [u'TurboGears', u'Flask', u'Django'], 
   'MediumOfInstruction': u'', 
   'AddressForCorrespondance': u'Shivaji Nagar\r\nNanded\r\nMaharashtra'
}

TurboGears — Валидация

Хорошая библиотека виджетов Forms должна иметь функцию проверки ввода. Например, пользователь должен быть вынужден ввести данные в обязательное поле или проверить, содержит ли поле электронной почты действительный адрес электронной почты, не прибегая к каким-либо другим программным средствам (таким как функция JavaScript) для проверки.

Ранние версии библиотеки форм ToscaWidgets использовались модулем FormEncode для поддержки проверки. ToscaWidgets2 теперь имеет встроенную поддержку проверки, доступную в модуле tw2.core. Тем не менее, все еще возможно использовать методы проверки FormEncode.

Для проверки формы ToscaWidgets используется @validate decorator.

@validate(form, error_handler, validators)
  • «Форма» — это объект формы ToscaWidgets, подлежащий проверке.

  • «Обработчик ошибок» — это метод контроллера, используемый для обработки ошибок формы.

  • «Валидаторы» — это объект словаря, содержащий валидаторы FormEncode.

«Форма» — это объект формы ToscaWidgets, подлежащий проверке.

«Обработчик ошибок» — это метод контроллера, используемый для обработки ошибок формы.

«Валидаторы» — это объект словаря, содержащий валидаторы FormEncode.

Типы валидаторов

Модуль tw2.core содержит класс валидатора, от которого наследуются другие валидаторы. Также возможно разработать собственный валидатор на его основе. Некоторые из важных валидаторов описаны ниже —

LengthValidator — Проверьте, имеет ли значение заданную длину. Минимальные и максимальные пределы определяются параметрами min и max. Пользовательские сообщения для длины ниже и выше мин и макс можно указать как параметр tooshort и toolong.

tw2.core.LengthValidator(min = minval, max = maxval, 
   msgs = { 'tooshort': (‘message for short length’), 
   'toolong': (‘message for long length)})

RangeValidator — обычно используется вместе с RangeField. Это полезно для проверки значения числового поля в пределах минимального и максимального пределов. Сообщения для параметров tooshort и toolong могут быть настроены.

tw2.core.RangeValidator(min = minval, max = maxval, 
   msgs = { 'tooshort': (‘message for short length’), 
   'toolong': (‘message for long length)})

IntValidator — этот класс является производным от RangeValidator. Обычно это используется для проверки, если ввод в обычном текстовом поле содержит целочисленные данные. Минимальные и максимальные пределы, а также сообщения об ошибках могут быть установлены. Кроме того, сообщение об ошибке для нецелочисленного ввода может быть указано как параметр notint.

tw2.core.IntValidator(msgs = {‘notint’:’Must be Integer’})

OneOfValidator — этот валидатор заставляет пользователя выбирать значение из доступных опций только в списке.

tw2.core.OneOfValidator(values = [option1, option2,..], 
   msgs = {‘notinlist’:’Not in List’}}

DateValidator — очень полезно, чтобы гарантировать, что пользовательский ввод является действительной датой. Формат даты (по умолчанию YMD) и сообщение об ошибке настраиваются. Минимальные и максимальные пределы даты также могут быть указаны. DateTimeValidator также доступен для проверки объекта класса DateTime.

tw2.core.DateValidator(msgs = {format = ’%Y-%m-%d’, 
   'baddatetime': ('baddate', ('Must follow date format $format_str'))}

EmailValidatorпроверяет ввод пользователя по действительному адресу электронной почты. Этот класс унаследован от более общего RegexValidator.

tw2.core.EmailValidator(msgs = {'badregex': ('bademail', 
   ('Must be a valid email address')) }

UrlValidator — этот класс также унаследован от RegexValidator. Он проверяет вводимые пользователем данные для действительного URL.

tw2.core.UrlValidator(msgs = {'badregex': ('badurl', ('Must be a valid URL’)) }

MatchValidator — подтверждает, сопоставлено ли значение одного поля с другим. Это особенно полезно, когда пользователь должен выбрать и подтвердить поле пароля. Типичное использование MatchValidator показано ниже —

import tw2.core as twc
import tw2.forms as twf
  
  class AdmissionForm(twf.Form):
      class child(twf.TableLayout):
         validator = twc.MatchValidator('pw', 'pwconfirm')
         pw = twf.PasswordField()
         pwconfirm = twf.PasswordField()

Также возможно построить составной валидатор, где валидация должна быть успешной, если какая-либо из проверок пройдена. В других случаях вы можете захотеть, чтобы проверка прошла успешно, только если входные данные прошли все проверки. Для этого tw2.core предоставляет валидаторы Any и All, которые являются подклассами расширяемого CompoundValidator.

TurboGears — Flash сообщения

TurboGears предоставляет очень удобную систему обмена сообщениями для уведомления пользователя в ненавязчивой форме. Класс TGFlash в модуле tg обеспечивает поддержку перепрошивки сообщений, которые хранятся в обычном cookie. Этот класс поддерживает выбор флэш-сообщений на стороне сервера, а также на стороне клиента через JavaScript.

Метод render () класса TGFlash, когда используется из самого Python, может быть вызван из шаблона для визуализации флеш-сообщения. Если используется на JavaScript, он предоставляет объект WebFlash. Он предоставляет методы payload () и render () для извлечения текущего флеш-сообщения и его рендеринга из JavaScript.

Когда проект TurboGears создается с помощью «быстрого старта», он имеет шаблон Master.html. Он содержит определение переменной этого flash-объекта. Содержимое этого флеш-сообщения, полученного от контроллера, заменяет отмеченный заполнитель в этом шаблоне.

<py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
   <div py:if = "flash" py:replace = "Markup(flash)" />
</py:with>

Tg.flash_obj — это объект WebFlash, который доступен внутри любого отрендеренного шаблона, включая шаблон master.html . Этот объект позволяет получить текущее флэш-сообщение и отобразить его.

Flash-сообщения хранятся в файле cookie (имя которого по умолчанию — webflash) с помощью метода tg.flash () . Сообщение и параметры состояния затем передаются ему.

tg.flash('Message', 'status')

Если метод, называемый flash, выполняет перенаправление, тогда flash будет виден внутри перенаправленной страницы. Если метод непосредственно предоставляет шаблон, то флэш-память будет видна внутри самого шаблона.

Внешний вид флеш-сообщения можно настроить, применив стиль CSS к коду состояния. «Быстрый старт» проекта содержит коды ошибок, предупреждений, информации и статуса ok, настроенные таблицей стилей public / css / style.css. Также можно добавить больше кодов состояния со стилями.

#flash > .warning {
   color: #c09853;
   background-color: #fcf8e3;
   border-color: #fbeed5;
}

#flash > .ok {
   color: #468847;
   background-color: #dff0d8;
   border-color: #d6e9c6;
}

#flash > .error {
   color: #b94a48;
   background-color: #f2dede;
   border-color: #eed3d7;
}

#flash > .info {
   color: #3a87ad;
   background-color: #d9edf7;
   border-color: #bce8f1;
}

Эта внешняя таблица стилей должна быть включена в шаблон —

<link rel = "stylesheet" type = "text/css" media = "screen" 
   href = "${tg.url('/css/style.css')}" />

Конфигурирование любой поддержки сообщений Flash может быть достигнуто путем установки параметров для метода configure () объекта TGFlash или в файле app_cfg.py (в папке config). Настраиваемые параметры:

Sr.No. Параметры и описание
1

flash.cookie_name

Имя файла cookie, используемого для хранения флеш-сообщений. По умолчанию используется webflash .

2

flash.default_status

Статус сообщения по умолчанию, если не указан (по умолчанию нормально)

3

flash.template

Используется как флэш-шаблон при визуализации.

4

flash.allow_html

Включает / выключает экранирование во флеш-сообщениях , по умолчанию HTML не разрешен.

5

flash.js_call

Код JavaScript, который будет запускаться при отображении flash из JavaScript. По умолчанию используется webflash.render ()

6

flash.js_template

Экземпляр string.Template используется для замены полной поддержки JavaScript для флеш-сообщений.

flash.cookie_name

Имя файла cookie, используемого для хранения флеш-сообщений. По умолчанию используется webflash .

flash.default_status

Статус сообщения по умолчанию, если не указан (по умолчанию нормально)

flash.template

Используется как флэш-шаблон при визуализации.

flash.allow_html

Включает / выключает экранирование во флеш-сообщениях , по умолчанию HTML не разрешен.

flash.js_call

Код JavaScript, который будет запускаться при отображении flash из JavaScript. По умолчанию используется webflash.render ()

flash.js_template

Экземпляр string.Template используется для замены полной поддержки JavaScript для флеш-сообщений.

  • pop_payload () — функция выбирает текущее флэш-сообщение, статус и связанную информацию. Получение флеш-сообщения приведет к удалению куки.

  • render (container_id, use_js = True) — визуализировать флеш-сообщение внутри шаблона или обеспечить поддержку Javascript для них.

  • container_id — это DIV, в котором будут отображаться сообщения, а use_js переключается между рендерингом флэш-памяти в формате HTML или для использования JavaScript.

  • status — Получить только текущее состояние Flash, получение статуса Flash удалит cookie.

  • сообщение — Получить только текущее флеш-сообщение, получение флеш-сообщения приведет к удалению куки.

pop_payload () — функция выбирает текущее флэш-сообщение, статус и связанную информацию. Получение флеш-сообщения приведет к удалению куки.

render (container_id, use_js = True) — визуализировать флеш-сообщение внутри шаблона или обеспечить поддержку Javascript для них.

container_id — это DIV, в котором будут отображаться сообщения, а use_js переключается между рендерингом флэш-памяти в формате HTML или для использования JavaScript.

status — Получить только текущее состояние Flash, получение статуса Flash удалит cookie.

сообщение — Получить только текущее флеш-сообщение, получение флеш-сообщения приведет к удалению куки.

Как сделать простое флеш сообщение?

В следующем примере метод flash () предоставляется в классе корневого контроллера. Вызывает сообщение flash (), которое отображается в предоставленном шаблоне flash.html.

from hello.lib.base import BaseController
from tg import expose, flash, redirect, request

class RootController(BaseController):
   @expose('hello.templates.flash')
   def flash(self, user = None):
      
      if user:
         flash(message = "Welcome "+user,status = "ok")
      else:
         flash(message = "Welcome Guest",status = "info")
      return {}

Код для создания flash.html в папке с шаблонами выглядит следующим образом

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   xmlns:xi = "http://www.w3.org/2001/XInclude">

   <head>
      <title>TurboGears 2.3: Flash messages>/title>
      <link rel = "stylesheet" type = "text/css" media = "screen"
         href = "${tg.url('/css/style.css')}" />
			
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
		
   </head>

   <body>
      <h2>Hello TurboGears</h2>
   </body>
	
</html>

Запустите сервер и введите в браузере http: // localhost: 8080 / flash? User = MVL

Флеш сообщение

Измените URL-адрес на http: // localhost: 8080 / flash и просмотрите флэш-сообщение, отформатированное в соответствии с определением в style.css

Сообщение

TurboGears — Cookies & Sessions

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

Однако данные сеанса в TurboGears могут быть поддержаны файловой системой, базой данных или хешированными значениями cookie. Небольшое количество данных сеанса обычно хранится в файлах cookie, но для большего объема данных сеанса используется MemCache.

MemCache — это демон системного уровня. Он обеспечивает быстрый доступ к кэшированным данным и чрезвычайно масштабируем. Однако он предназначен для использования только на защищенных серверах и, следовательно, должен поддерживаться и защищаться сисадмином.

Стакан в управлении сессиями

TurboGears использует Beaker для управления сессиями. Проект, запущенный с помощью коробки передач, по умолчанию настроен на использование хешированных файлов cookie для хранения данных сеанса.

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

Чтобы включить управление сеансом, класс сеанса должен быть включен в проект, следуя инструкции import —

from tg import session

Чтобы сохранить данные в переменной сеанса —

session[‘key’] = value
session.save()

Чтобы получить переменную сеанса —

return session[‘key’]

Обратите внимание, что вам нужно явно сохранить сеанс, чтобы ваши ключи были сохранены в этом сеансе.

Метод delete () объекта сеанса удалит все сеансы пользователя —

session.delete()

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

Ниже приведен простой пример демонстрации сессий. Класс RootController имеет метод setsession (), который устанавливает переменную сеанса.

from hello.lib.base import BaseController
from tg import expose, session
class RootController(BaseController):
   
   @expose()
   def setsession(self):
      session['user'] = 'MVL'
      session.save()
      
      str = "<b>sessionVariable set to "+session['user'] 
      str = str+"<br><a href = '/getsession'>click here to retrieve</a></b>"
      return str
   
   @expose()
   def getsession(self):
      return "<b>value of session variable retrieved " +session['user'] +"</b>"

Введите http: // localhost: 8080 / setsession

сессия

Ссылка в браузере ведет на http: // localhost: 8080 / getsession, который извлекает и отображает переменную сеанса —

переменная

TurboGears — Кэширование

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

Кеширование целых страниц

Он работает на уровне протокола HTTP, чтобы избежать полных запросов к серверу, поскольку браузер пользователя или промежуточный прокси-сервер (например, Squid) перехватывают запрос и возвращают кэшированную копию файла.

Кэширование на уровне приложения

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

Кэширование на уровне приложения

Как упоминалось ранее, проект «быстрого запуска» TurboGears настроен на включение пакета Beaker для поддержки кэширования. Beaker поддерживает следующие бэкэнды, используемые для хранения кеша:

  • память — используется для хранения на процесс. Это очень быстро.

  • файловая система — для каждого процесса хранения, а также многопроцессорные.

  • База данных DBM — для каждого процесса, многопроцессная, довольно быстрая.

  • База данных SQLAlchemy — хранилище для каждой базы данных на сервере. Более медленный по сравнению с приведенными выше вариантами.

  • Memcached — многосерверный кеш на основе памяти.

память — используется для хранения на процесс. Это очень быстро.

файловая система — для каждого процесса хранения, а также многопроцессорные.

База данных DBM — для каждого процесса, многопроцессная, довольно быстрая.

База данных SQLAlchemy — хранилище для каждой базы данных на сервере. Более медленный по сравнению с приведенными выше вариантами.

Memcached — многосерверный кеш на основе памяти.

Кэширование контроллера

Для быстрого кэширования контроллера доступен декоратор cached () . Все тело контроллера кэшируется в зависимости от различных параметров запроса. Определение декоратора tg.decorators.cached () следующее

tg.decorators.cached(key, expire, type, 
   query-args, cache_headers, invalidate_on_startup, cache_response)

Описание параметров выглядит следующим образом —

Sr.No. Параметры и описание
1

ключ

Определяет параметры контроллера, используемые для генерации ключа кэша.

2

истекать

Время в секундах до истечения срока действия кэша. По умолчанию «никогда».

3

Тип

dbm, память, файл, memcached или None.

4

cache_headers

Кортеж имен заголовков, указывающих заголовки ответа.

5

invalidate_on_startup

Если True, кеш становится недействительным каждый раз, когда приложение запускается или перезапускается.

6

cache_response

ответ должен быть кэширован или нет, по умолчанию True.

ключ

Определяет параметры контроллера, используемые для генерации ключа кэша.

истекать

Время в секундах до истечения срока действия кэша. По умолчанию «никогда».

Тип

dbm, память, файл, memcached или None.

cache_headers

Кортеж имен заголовков, указывающих заголовки ответа.

invalidate_on_startup

Если True, кеш становится недействительным каждый раз, когда приложение запускается или перезапускается.

cache_response

ответ должен быть кэширован или нет, по умолчанию True.

Ниже приведен пример кэширования контроллера:

@cached(expire = 100, type = 'memory')
@expose()
def simple(self):
   return "This is a cached controller!"

Кэширование на уровне шаблона

Механизм шаблонов Genshi извлекает шаблон из кэша, если его содержимое не изменилось. Размер этого кэша по умолчанию — 25. По умолчанию автоматическая перезагрузка шаблонов имеет значение true. Чтобы повысить производительность, в app_cfg.py можно сделать следующие настройки:

[app:main]
genshi.max_cache_size = 100
auto_reload_templates = false

Чтобы кэшировать шаблон, вам просто нужно вернуть параметр tg_cache из контроллера, который отображает кэшированный шаблон.

Tg_cache — это словарь, который принимает следующие ключи:

  • ключ — ключ кеша. По умолчанию: нет.

  • expire — как долго кэш должен оставаться в живых. По умолчанию: никогда не истекает

  • тип — память, дбм, memcached. По умолчанию: дБм.

ключ — ключ кеша. По умолчанию: нет.

expire — как долго кэш должен оставаться в живых. По умолчанию: никогда не истекает

тип — память, дбм, memcached. По умолчанию: дБм.

Следующий пример иллюстрирует кеширование шаблона:

@expose(hello.templates.user')
def user(self, username):
   return dict(user = username, tg_cache = dict(key = user, expire = 900))

TurboGears — SQLAlchemy

Хотя можно использовать SQL в приложении TurboGears для выполнения операций CRUD с любой реляционной базой данных, рекомендуется использовать SQLAlchemy, набор инструментов Python — это мощный инструмент сопоставления объектов, который дает разработчикам приложений полную мощь и гибкость SQL. В дополнение к поддержке баз данных на основе SQL через SQLAlchemy, TurboGears также поддерживает базу данных MongoDB через Ming. В этом разделе обсуждается функциональность SQLAlchemy.

SQL

Что такое ORM (объектно-реляционное сопоставление)?

Большинство платформ языка программирования являются объектно-ориентированными. С другой стороны, данные на серверах РСУБД хранятся в виде таблиц. Сопоставление объектных отношений — это метод сопоставления параметров объекта с базовой структурой таблицы СУБД. API ORM предоставляет методы для выполнения операций CRUD без необходимости писать необработанные операторы SQL.

Орм

Когда проект TurboGears создается с помощью команды «быстрый старт» из набора инструментов коробки передач, поддержка SQLAlchemy по умолчанию включается следующими параметрами конфигурации:

config['use_sqlalchemy'] = True
config['sqlalchemy.url'] = 'sqlite:///devdata.db'

«Быстрый старт» проекта также создает пакет моделей внутри него. Например, у проекта «Hello» будет Hello \ hello \ model. Следующие файлы создаются в этом пакете —

  • __init__.py — здесь настраивается доступ к базе данных. Объекты модели приложения импортируются в этот модуль. Он также имеет DBSession — глобальный менеджер сеансов, а также DeclarativeBase, который является базовым классом для всех классов моделей.

  • auth.py — здесь определяются модели, используемые стеком аутентификации. Дополнительные модели базы данных хранятся в этом пакете как отдельный модуль и добавляются в файл __init__.py.

__init__.py — здесь настраивается доступ к базе данных. Объекты модели приложения импортируются в этот модуль. Он также имеет DBSession — глобальный менеджер сеансов, а также DeclarativeBase, который является базовым классом для всех классов моделей.

auth.py — здесь определяются модели, используемые стеком аутентификации. Дополнительные модели базы данных хранятся в этом пакете как отдельный модуль и добавляются в файл __init__.py.

TurboGears — Создание моделей

Давайте добавим модель студента, которая настроит таблицу студента в нашей базе данных sqlite .

Привет \ привет \ модель \ student.py

from sqlalchemy import *
from sqlalchemy.orm import mapper, relation, relation, backref
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode, DateTime

from hello.model import DeclarativeBase, metadata, DBSession
from datetime import datetime

class student(DeclarativeBase):
   __tablename__ = 'student'

   uid = Column(Integer, primary_key = True)
   name = Column(Unicode(20), nullable = False, default = '')
   city = Column(Unicode(20), nullable = False, default = '')
   address = Column(Unicode(100), nullable = False, default = '')
   pincode = Column(Unicode(10), nullable = False, default = '')

Теперь добавьте эту модель в функцию init_model () внутри __init__.py. Эта функция уже содержит в себе модель аутентификации. Добавьте нашу модель студента ниже.

# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student

Если вы хотите, чтобы таблица была инициализирована с некоторыми данными во время настройки моделей, добавьте ее в bootstrap.py в пакете websetup. Добавьте следующие операторы в функцию bootstrap () .

s1 = model.student()
s1.name = 'M.V.Lathkar'
s1.city = 'Nanded'
s1.address = 'Shivaji Nagar'
s1.pincode = '431602'

model.DBSession.add(s1)
model.DBSession.flush()
transaction.commit()

Модели инициализируются с помощью команды setup-app на коробке передач —

gearbox setup-app

Объект сеанса SQLAlchemy управляет всеми операциями сохранения объекта ORM.

TurboGears — CRUD-операции

Следующие методы сеанса выполняют операции CRUD —

  • DBSession.add (объект модели) — вставляет запись в отображаемую таблицу.

  • DBSession.delete (объект модели) — удаляет запись из таблицы.

  • DBSession.query (model) .all () — извлекает все записи из таблицы (соответствует запросу SELECT).

DBSession.add (объект модели) — вставляет запись в отображаемую таблицу.

DBSession.delete (объект модели) — удаляет запись из таблицы.

DBSession.query (model) .all () — извлекает все записи из таблицы (соответствует запросу SELECT).

Вы можете применить фильтр к полученному набору записей, используя атрибут фильтра. Например, чтобы получить записи с city = ‘Hyderabad’ в таблице студентов, используйте следующий оператор —

DBSession.query(model.student).filter_by(city = ’Hyderabad’).all()

Теперь мы увидим, как взаимодействовать с моделями через URL контроллера.

Сначала давайте разработаем форму ToscaWidgets для ввода данных учащегося

Привет \ привет \ controllers.studentform.py

import tw2.core as twc
import tw2.forms as twf

class StudentForm(twf.Form):
   class child(twf.TableLayout):
      name = twf.TextField(size = 20)
      city = twf.TextField()
      address = twf.TextArea("",rows = 5, cols = 30)
      pincode = twf.NumberField()

   action = '/save_record'
   submit = twf.SubmitButton(value = 'Submit')

В RootController (root.py приложения Hello) добавьте следующую функцию, отображающую URL «/ add» —

from hello.controllers.studentform import StudentForm

class RootController(BaseController):
   @expose('hello.templates.studentform')
   def add(self, *args, **kw):
      return dict(page='studentform', form = StudentForm)

Сохраните следующий HTML-код как studentform.html в папке шаблонов —

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
   
   <head>
      <title>Student Registration Form</title>
   </head>
   
   <body>
      <div id = "getting_started">
         ${form.display(value = dict(title = 'Enter data'))}
      </div>
   </body>

</html>

Введите http: // localhost: 8080 / add в браузере после запуска сервера. Следующая информация о студентах откроется в браузере —

Постановка на учет

Приведенная выше форма предназначена для отправки по URL адресу ‘/ save_record’ . Следовательно, необходимо добавить функцию save_record () в root.py, чтобы открыть ее. Данные из формы Student получены этой функцией как объект dict () . Он используется для добавления новой записи в таблицу учеников, лежащую в основе модели ученика.

@expose()
#@validate(form = AdmissionForm, error_handler = index1)

def save_record(self, **kw):
   newstudent = student(name = kw['name'],city = kw['city'],
      address = kw['address'], pincode = kw['pincode'])
   DBSession.add(newstudent)
   flash(message = "new entry added successfully")
   redirect("/listrec")

Обратите внимание, что после успешного добавления браузер будет перенаправлен на URL-адрес «/ listrec» . Этот URL предоставляется функцией listrec () . Эта функция выбирает все записи в таблице студентов и отправляет их в виде объекта dict в шаблон studentlist.html. Эта функция listrec () выглядит следующим образом:

@expose ("hello.templates.studentlist")
def listrec(self):
   entries = DBSession.query(student).all()
   return dict(entries = entries)

Шаблон studentlist.html выполняет итерацию по объекту словаря записей с использованием директивы py: for. Шаблон studentlist.html выглядит следующим образом:

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/">
   
   <head>
      <link rel = "stylesheet" type = "text/css" media = "screen" 
         href = "${tg.url('/css/style.css')}" />
      <title>Welcome to TurboGears</title>
   </head>
   
   <body>
      <h1>Welcome to TurboGears</h1>
      
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
      
      <h2>Current Entries</h2>
      
      <table border = '1'>
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pincode</th>
            </tr>
         </thead>
         
         <tbody>
            <py:for each = "entry in entries">
               <tr>
                  <td>${entry.name}</td>
                  <td>${entry.city}</td>
                  <td>${entry.address}</td>
                  <td>${entry.pincode}</td>
               </tr>
            </py:for>
         </tbody>
         
      </table>
   
   </body>
</html>

Теперь снова посетите http: // localhost: 8080 / add и введите данные в форму. Нажав на кнопку «Отправить», вы перейдете в браузер к studentlist.html. Также будет отображено сообщение «новая запись добавлена ​​успешно».

Записи

TurboGears — DataGrid

ToscaWidgets содержит элемент управления DataGrid, который обеспечивает быстрый способ представления данных в табличной форме. Объект DataGrid объявлен следующим образом:

from tw2.forms import DataGrid
student_grid = DataGrid(fields = [('Name', 'name'),('City', 'city'),
   ('Address','address'), ('PINCODE', 'pincode')])

Теперь функция showgrid () извлекает все записи в таблице учеников и предоставляет данные в шаблон grid.html. Сначала приведен код для функции showgrid (), а затем код grid.html:

ShowGrid ()

@expose('hello.templates.grid')
def showgrid(self):
   data = DBSession.query(student).all()
   return dict(page = 'grid', grid = student_grid, data = data)

grid.html

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
   
   <head>
      <title>Student Registration Form</title>
   </head>
   
   <body>
      <div id = "getting_started">
         <div>${grid.display(value = data)}</div>
      </div>
   </body>

</html>

Следующие табличные данные будут отображаться при вводе URL-адреса http: // localhost: 8080 / showlist в браузере —

форма

TurboGears — нумерация страниц

TurboGears предоставляет удобный декоратор paginate () для разделения вывода на страницах. Этот декоратор сочетается с декоратором expose (). Декоратор @Paginate () принимает в качестве аргумента объект словаря результата запроса. Кроме того, количество записей на странице определяется значением атрибута items_per_page. Убедитесь, что вы импортируете функцию paginate из tg.decorators в ваш код.

Перепишите функцию listrec () в root.py следующим образом:

from tg.decorators import paginate
class RootController(BaseController):
   @expose ("hello.templates.studentlist")
   @paginate("entries", items_per_page = 3)
	
   def listrec(self):
      entries = DBSession.query(student).all()
      return dict(entries = entries)

Количество элементов на странице должно быть три.

В шаблоне studentlist.html навигация по страницам включается путем добавления tmpl_context.paginators.entries.pager () под директивой py: for. Код для этого шаблона должен быть следующим:

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/">
   
   <head>
      <link rel = "stylesheet" type = "text/css" media = "screen" 
         href = "${tg.url('/css/style.css')}" />
      <title>Welcome to TurboGears</title>
   </head>
   
   <body>
      
      <h1>Welcome to TurboGears</h1>
		
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
      
      <h2>Current Entries</h2>
		
      <table border = '1'>
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pincode</th>
            </tr>
         </thead>
         
         <tbody>
            <py:for each = "entry in entries">
               <tr>
                  <td>${entry.name}</td>
                  <td>${entry.city}</td>
                  <td>${entry.address}</td>
                  <td>${entry.pincode}</td>
               </tr>
            </py:for>
				
            <div>${tmpl_context.paginators.entries.pager()}</div>
         </tbody>
         
      </table>
   
   </body>

</html>

Введите http: // localhost: 8080 / listrec в браузере. Первая страница записей в таблице отображаются. Вверху этой таблицы также отображаются ссылки на номера страниц.

запись

Как добавить поддержку пагинации в Datagrid

Также возможно добавить поддержку пагинации в datagrid. В следующем примере разбитая на страницы сетка данных предназначена для отображения кнопки действия. Для активации кнопки действия строится объект datagrid со следующим кодом —

student_grid = DataGrid(fields = [('Name', 'name'),('City', 'city'),
   ('Address','address'), ('PINCODE', 'pincode'),
   ('Action', lambda obj:genshi.Markup('<a
      href = "%s">Edit</a>' % url('/edit',
      params = dict(name = obj.name)))) ])

Здесь кнопка действия связана с параметром имени каждой строки в сетке данных.

Перепишите функцию showgrid () следующим образом:

@expose('hello.templates.grid')
@paginate("data", items_per_page = 3)

def showgrid(self):
   data = DBSession.query(student).all()
   return dict(page = 'grid', grid = student_grid, data = data)

Браузер показывает разбитую на страницы сетку данных следующим образом:

Форма регистрации

Нажав кнопку «Изменить» в третьей строке, он будет перенаправлен на следующий URL-адрес http: // localhost: 8080 / edit? Name = Rajesh + Patil

TurboGears — доступ администратора

TurboGears предоставляет расширение tgext.admin, которое работает на tgext.crud и sprox. Этот Sprox представляет собой пакет, используемый для создания веб-виджетов непосредственно из схемы базы данных. Это может быть использовано для автоматического создания простых страниц администрирования и является инструментарием для включения страницы / admin в недавно запущенные приложения.

По умолчанию администратор предоставляет автоматически сгенерированный доступ ко всем моделям, импортированным в модели вашего проекта / __ init__.py.

Как создать TurboGears Admin

Администратор TurboGears по умолчанию создается как объект класса AdminController —

from tgext.admin.controller import AdminController

class RootController(BaseController):
   admin = AdminController(model, DBSession, config_type = TGAdminConfig)

Это создает администратора для всех моделей с конфигурацией администратора TurboGears по умолчанию.

Через менеджера пользователь был создан на этапе установки. Теперь можно получить доступ к администратору TurboGears по адресу http: // localhost: 8080 / admin При первом обращении к этой странице она запросит аутентификацию. Вы можете просто предоставить имя пользователя и пароль пользователя, который команда setup-app создала для нас —

Username: manager
Password: managepass

Чтобы войти в проект с быстрым стартом, добавьте следующие функции в класс RootController (controllers / root.py).

from hello.lib.base import BaseController
from tg import expose, flash, redirect, request,url, lurl
from tg import redirect, validate
from hello import model
from hello.model import DBSession
from tgext.admin.tgadminconfig import BootstrapTGAdminConfig as TGAdminConfig
from tgext.admin.controller import AdminController
from tg.exceptions import HTTPFound

class RootController(BaseController):
   admin = AdminController(model, DBSession, config_type =  TGAdminConfig)
   
   @expose('hello.templates.index')
   def index(self):
      return dict(page = 'index')
   
   @expose('hello.templates.login')
   def login(self, came_from = lurl('/'), failure = None,    login = ''):
	
      if failure is not None:
         if failure == 'user-not-found':
            flash(_('User not found'), 'error')
         elif failure == 'invalid-password':
            flash(_('Invalid Password'), 'error')
			
      login_counter = request.environ.get('repoze.who.logins', 0)
		
      if failure is None and login_counter > 0:
         flash(_('Wrong credentials'), 'warning')
		 
      return dict(page = 'login', login_counter = str(login_counter), 
         came_from = came_from, login = login)
   @expose()
	
   def post_login(self, came_from = lurl('/')):
      if not request.identity:
         
         login_counter = request.environ.get('repoze.who.logins', 0) + 1
            redirect('/login', params = dict(came_from = came_from,
            __logins = login_counter))
		
         userid = request.identity['repoze.who.userid']
         flash(('Welcome back, %s!') % userid)
			
         return HTTPFound(location = came_from)

Войдите в приложение «quickstarted» после запуска сервера и перейдите по адресу http: // localhost: 8080 / login, а затем введите учетные данные менеджера, как показано выше. Браузер отобразит страницу администратора, как показано ниже —

Админ паде

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

Студенческий листинг

Кнопка «Создать» в верхней части этой сетки данных позволяет добавить запись. Аналогично, кнопки действий для редактирования и удаления записи также предусмотрены в столбце действий этой таблицы данных. Также отображается окно поиска для условного выбора записей.

DataGrid

TurboGears — авторизация и аутентификация

Приложение TurboGears создается с помощью параметров быстрого запуска и настройки приложения инструментария коробки передач, для которых по умолчанию включена поддержка авторизации и аутентификации. Модели, объявленные в auth.py, устанавливаются и инициализируются в соответствии со значениями, заданными в bootstrap.py.

Следующие модели объявлены в auth.py —

Модель пользователя

Модель User содержит дизайн таблицы tg_user. Эта таблица используется пакетом repose.who. Этот пакет repose.who является мощной и расширяемой библиотекой аутентификации для приложений WSGI. Структура пользовательской модели выглядит следующим образом:

class User(DeclarativeBase):

"""
   __tablename__ = 'tg_user'
   
   user_id = Column(Integer, autoincrement = True, primary_key=True)
   user_name = Column(Unicode(16), unique = True, nullable = False)
   email_address = Column(Unicode(255), unique = True,nullable=False)
                                             
   display_name = Column(Unicode(255))
   _password = Column('password', Unicode(128))
   created = Column(DateTime, default = datetime.now)

Эта групповая модель содержит определение таблицы tg_group. Его определение дано в auth.py следующим образом:

class Group(DeclarativeBase):
   __tablename__ = 'tg_group'
   
   group_id = Column(Integer, autoincrement = True,primary_key = True)
   group_name = Column(Unicode(16),unique = True,nullable = False)
   display_name = Column(Unicode(255))
   created = Column(DateTime, default = datetime.now)

Также настроено другое разрешение модели, которое содержит определение разрешения.

class Permission(DeclarativeBase):
   __tablename__ = 'tg_permission'
   
   permission_id = Column(Integer,autoincrement = True,primary_key = True)
   permission_name = Column(Unicode(63), unique = True, nullable = False)
   description = Column(Unicode(255))

Во время настройки моделей в эти таблицы добавляются следующие данные:

u = model.User()
u.user_name = 'manager'
u.display_name = 'Example manager'
u.email_address = 'manager@somedomain.com'
u.password = 'managepass'

model.DBSession.add(u)
g = model.Group()
g.group_name = 'managers'
g.display_name = 'Managers Group'
g.users.append(u)

model.DBSession.add(g)
p = model.Permission()
p.permission_name = 'manage'
p.description = 'This permission gives an administrative right'
p.groups.append(g)

model.DBSession.add(p)
u1 = model.User()
u1.user_name = 'editor'
u1.display_name = 'Example editor'
u1.email_address = 'editor@somedomain.com'
u1.password = 'editpass'

model.DBSession.add(u1)

Модель предиката

Модуль предикатов в пакете tg содержит определения для проверки предикатов. Предикат — это условие, которое должно быть выполнено, чтобы пользователь мог получить доступ к запрошенному источнику. Такой предикат или условие может состоять из большего числа предикатов — они называются составными предикатами. Контроллеры действий или контроллеры могут иметь только один предикат, будь то отдельный или составной.

Если пользователь не вошел в систему или не имеет надлежащих разрешений, эта программа проверки предикатов выбрасывает 401 (HTTP Unauthorized), который перехватывается промежуточным программным обеспечением repoze.who, чтобы отобразить страницу входа, позволяющую пользователю войти в систему, и перенаправить пользователь вернется на соответствующую страницу, когда они будут сделаны.

Различные условия или предикаты, определенные в модуле tg.predicates:

Sr.No. Модуль и описание tg.predicates
1

Все

Проверьте, выполнены ли все указанные предикаты

2

любой

Проверьте, соответствует ли хотя бы один из указанных предикатов

3

is_user

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

4

в группе

Убедитесь, что пользователь принадлежит к определенной группе.

5

in_all_groups

Убедитесь, что пользователь принадлежит ко всем указанным группам.

6

in_any_group

Убедитесь, что пользователь принадлежит хотя бы к одной из указанных групп.

7

is_anonymous

Убедитесь, что текущий пользователь является анонимным.

8

has_permission

Убедитесь, что текущий пользователь имеет указанное разрешение.

9

has_all_permissions

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

10

has_any_permission

Убедитесь, что у пользователя есть хотя бы одно из указанных разрешений.

Все

Проверьте, выполнены ли все указанные предикаты

любой

Проверьте, соответствует ли хотя бы один из указанных предикатов

is_user

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

в группе

Убедитесь, что пользователь принадлежит к определенной группе.

in_all_groups

Убедитесь, что пользователь принадлежит ко всем указанным группам.

in_any_group

Убедитесь, что пользователь принадлежит хотя бы к одной из указанных групп.

is_anonymous

Убедитесь, что текущий пользователь является анонимным.

has_permission

Убедитесь, что текущий пользователь имеет указанное разрешение.

has_all_permissions

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

has_any_permission

Убедитесь, что у пользователя есть хотя бы одно из указанных разрешений.

Например, если у вас есть предикат, то есть пользователь с разрешенным доступом, принадлежащий к группе клиентов , вы можете использовать следующую встроенную проверку предикатов:

from tg.predicates import in_group
p in_group(‘customers’)

Следующая проверка предикатов предоставит доступ пользователю root или кому-либо с правами на управление:

from tg.predicates import Any, is_user, has_permission
p = Any(is_user('root'), has_permission('manage'), 
   sg = 'Only administrators can remove blog posts')

TurboGears — Использование MongoDB

TurboGears также поддерживает базы данных документов MongoDB. Он использует Ming, API Object Document Mapper. Использование Ming очень похоже на SQLAlchemy. Язык запросов Ming позволяет портировать проект TurboGears на основе SQLAlchemy в Ming.

Что такое PyMongo

PyMongo — это дистрибутив Python, содержащий инструменты для работы с MongoDB. Ming расширяет возможности PyMongo —

  • Декларативные модели
  • Проверка схемы и преобразование
  • Схема Эволюция
  • Внедрение Pure InMemory MongoDB
  • Единица работы
  • Карта личности
  • Отношения один-ко-многим, многие-к-одному и многие-ко-многим

Прежде всего, вам необходимо скачать и установить MongoDB. Последний дистрибутив MongoDB можно скачать по адресу https://www.mongodb.org/downloads.

В Windows запустите сервер MongoDB, указав опцию -dbpath —

C:\mongodb\bin>Mongod --dbpath d:\mongo

Папка D: \ mongo предназначена для хранения базы данных MongoDB. Сервер начинает прослушивание по адресу http: // localhost: 27017. Теперь для запуска оболочки MongoDB используйте следующую команду —

C:\mongodb\bin>Mongo

Наша среда MongoDB теперь готова.

Теперь создайте проект TurboGears с опцией -ming —

gearbox quickstart --ming Hello

Этот проект с быстрым запуском обеспечит уровень аутентификации и авторизации, подобный тому, который предоставляется для версии SQLAlchemy. Это приложение теперь попытается подключиться к серверу через порт 27017 на локальном компьютере. Файл development.ini в папке проекта содержит следующие параметры:

ming.url = mongodb://localhost:27017/
ming.db = hello

Настройте проект с помощью следующей команды —

Python setup.py develop

Папка проекта содержит подпапку моделей, в которой находятся следующие файлы:

  • __init__.py — здесь настраивается доступ к базе данных . Ваши коллекции должны быть импортированы в этот модуль . Например, мы добавим студенческую коллекцию в этот пакет.

  • session.py — Этот файл определяет сеанс подключения к вашей базе данных . Вам нужно будет импортировать это каждый раз, когда вам нужно объявить MappedClass, чтобы указать сеанс для выполнения запросов .

  • auth.py — этот файл будет создан, если вы включили аутентификацию и авторизацию в быстром запуске . Он определяет три коллекции repoze .who, которые также зависят от: User, Group и Permission.

__init__.py — здесь настраивается доступ к базе данных . Ваши коллекции должны быть импортированы в этот модуль . Например, мы добавим студенческую коллекцию в этот пакет.

session.py — Этот файл определяет сеанс подключения к вашей базе данных . Вам нужно будет импортировать это каждый раз, когда вам нужно объявить MappedClass, чтобы указать сеанс для выполнения запросов .

auth.py — этот файл будет создан, если вы включили аутентификацию и авторизацию в быстром запуске . Он определяет три коллекции repoze .who, которые также зависят от: User, Group и Permission.

Определение вашей коллекции

По умолчанию TurboGears настраивает Ming в декларативном режиме. Это похоже на декларативную поддержку SQLAlchemy, и каждая модель должна наследоваться от класса MappedClass.

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

MappedClass также содержит определение полей в документе. Модуль Odm от Ming имеет определения различных типов свойств полей —

  • FieldProperty
  • ForeignIdProperty
  • RelationProperty

Модуль ming.schema определяет следующие типы данных —

  • ming.schema.Anything
  • ming.schema.Array
  • ming.schema.Binary
  • ming.schema.Bool
  • ming.schema.Float
  • ming.schema.Int
  • ming.schema.ObjectId
  • ming.schema.Scalar
  • ming.schema.String

Чтобы добавить коллекцию учеников в эту модель, сохраните следующий код как student.py в папке hello / models.

Привет \ модели \ student.py

from ming import schema
from ming.odm import MappedClass
from ming.odm import FieldProperty, ForeignIdProperty
from hello.model import DBSession
   
Class student(MappedClass):
   class __mongometa__:
      session = DBSession
      name = 'student'
      
   _id = FieldProperty(schema.ObjectId)
   name = FieldProperty(schema.String(required = True))
   city = FieldProperty(schema.String(if_missing = ''))
   address = FieldProperty(schema.String(if_missing = ''))
   pincode = FieldProperty(schema.String(if_missing = ''))

Наконец, включите эту модель в hello \ models \ __ init__.py

# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student

Чтобы настроить эти модели, выполните следующую команду коробки передач —

Gearbox setup-app

Запустите сервер с помощью следующей команды коробки передач —

Gearbox serve –reload –debug

Откройте домашнюю страницу этого приложения (http: // localhost: 8080 /) и войдите с учетными данными менеджера. Страница администратора этого приложения покажет список настроенных моделей. (войдите как менеджер, пароль паролей)

Домашняя страница приложения

Создание коллекций также можно проверить в веб-интерфейсе MongoDB и в оболочке MongoDB.

ODMSession используется для выполнения нескольких операций с базой данных с использованием следующих функций:

  • model.query.find ()
  • model.query.find_and_modify ()
  • model.remove ()
  • model.update ()
  • model.flush ()

Разработка формы ToscoWidget

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

Ниже приведен код для создания studentform.py —

Привет \ Контроллеры \ studentform.py

import tw2.core as twc
import tw2.forms as twf
   
class StudentForm(twf.Form):

   class child(twf.TableLayout):
      name = twf.TextField(size = 20)
      city = twf.TextField()
      address = twf.TextArea("",rows = 5, cols = 30)
      pincode = twf.NumberField()
		
   action = '/save_record'
   submit = twf.SubmitButton(value = 'Submit')     

В URL-адресе приложения / Rootcontroller ‘/ add’, который вызывает функцию add (), которая откроет вышеуказанную форму в браузере. Затем кнопка «Отправить» вызывает функцию save_record (). Он извлекает данные формы и сохраняет их в таблице учеников и перенаправляет приложение на URL-адрес «/ listrec», который предоставляет шаблон списка учеников.

Root.py для этого действия выглядит следующим образом —

Привет / Контроллеры / root.py

from hello.lib.base import BaseController
from tg import expose, flash, redirect, request,url, lurl
from tg import redirect, validate
from hello import model
from hello.model import DBSession
from hello.model.student import student
   
from hello.controllers.studentform import StudentForm
   
class RootController(BaseController):
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
         
   @expose ("hello.templates.studentlist")
   def listrec(self):
      entries = student.query.find()
      return dict(entries = entries)
               
   @expose('hello.templates.studentform')
   def add(self, *args, **kw):
      return dict(page = 'studentform', form = StudentForm)
         
   @expose()
   def save_record(self, **kw):
      newstudent = student(name = kw['name'],city = kw['city'],
         address = kw['address'], pincode = kw['pincode'])
      DBSession.flush()
      flash(message = "new entry added successfully")
      redirect("/listrec")

Следующие шаблоны создаются в папке шаблонов —

Привет \ Шаблоны \ studentform.html

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/" lang = "en">
	
   <head>
      <title>Student Registration Form</title>
   </head>
	

   <body>
      <div id = "getting_started">
         ${form.display(value = dict(title = 'Enter data'))}
      </div>
   </body>
	
</html>

Привет \ Шаблоны \ studentlist.html

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/">

   <head>
      <link rel = "stylesheet" type = "text/css" media = "screen" 
         href = ${tg.url('/css/style.css')}" />
      <title>Welcome to TurboGears</title>
   </head>
   
   <body>
      <h1>Welcome to TurboGears</h1>
		
      <py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
         <div py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
      
      <h2>Current Entries</h2>
		
      <table border = '1'>
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pincode</th>
            </tr>
         </thead>
         
         <tbody>
            <py:for each = "entry in entries">
               <tr>
                  <td>${entry.name}</td>
                  <td>${entry.city}</td>
                  <td>${entry.address}</td>
                  <td>${entry.pincode}</td>
               </tr>
            </py:for>
         </tbody>
      </table>
		
   </body>
	
</html>

Перезагрузите сервер и введите в браузере http: // localhost: 8080 / add

Форма регистрации студента

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

Новая запись выхода

TurboGears — Строительные леса

Инструментарий Gearbox содержит команду scaffold, которая очень полезна для быстрого создания новых компонентов приложения TurboGears. Приложение, созданное командой quickstart для gearbox, имеет шаблон каркаса в папке модели (model.py.template), папку шаблонов (template.html.template) и папку контроллеров (controller.py.template). Эти файлы .template используются в качестве основы для создания новых скаффолдов для приложения.

Например, чтобы создать новую модель с именем mymodel, просто выполните следующую команду —

gearbox scaffold model mymodel

Эта команда сгенерирует модель / mymodel.py с определенным в ней классом newmodel.

# -*- coding: utf-8 -*-
"""Mymodel model module."""
from sqlalchemy import *
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode, DateTime, LargeBinary
from sqlalchemy.orm import relationship, backref
from hello.model import DeclarativeBase, metadata, DBSession

class Mymodel(DeclarativeBase):
   __tablename__ = 'mymodels'
   
   uid = Column(Integer, primary_key = True)
   data = Column(Unicode(255), nullable = False)
   
   user_id = Column(Integer, ForeignKey('tg_user.user_id'), index = True)
   user = relationship('User', uselist = False,
      backref = backref('mymodels',cascade = 'all, delete-orphan'))
   __all__ = ['Mymodel']

Теперь пользователи могут вносить изменения в структуру таблицы в соответствии со своими требованиями, а затем импортировать ее в модель / __ init__.py, чтобы сделать модель доступной внутри приложения.

Чтобы создать модель, класс контроллера для ее обработки и индексную страницу, все эти три компонента могут быть созданы одновременно с помощью следующей команды.

gearbox scaffold model controller template mymodel

Эта команда приведет к controllers \ mymodel.py, в котором класс MymodelController должным образом определен.

# -*- coding: utf-8 -*-
"""Mymodel controller module"""

from tg import expose, redirect, validate, flash, url
# from tg.i18n import ugettext as _
# from tg import predicates

from hello.lib.base import BaseController
# from hello.model import DBSession

class MymodelController(BaseController):
   # Uncomment this line if your controller requires an authenticated user
   # allow_only = predicates.not_anonymous()
   
   @expose('hello.templates.mymodel')
   def index(self, **kw):
      return dict(page = 'mymodel-index')

Чтобы начать использовать этот контроллер, смонтируйте его внутри RootController вашего приложения, просто чтобы определить экземпляр MymodelController. Добавьте эти строки в controllers \ root.py —

From hello.controller.mymodel import MymodelController

class RootController(BaseController): mymodel = MymodelController()

Шаблон scaffold templates \ mymodel.html также будет создан в папке шаблонов. Он будет выступать в качестве индексной страницы для URL / mymodel.

Сгенерированный файл mymodel.html в папке шаблонов будет выглядеть следующим образом:

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   xmlns:xi = "http://www.w3.org/2001/XInclude">
	
   <xi:include href = "master.html" />
	
   <head>
      <title>Mymodel</title>
   </head>
	
   <body>
      <div class = "row">
         <div class = "col-md-12">
            <h2>Mymodel</h2>
            <p>Template page for Mymodel</p>
         </div>
      </div>
   </body>
	
</html>

TurboGears — Крючки

В TurboGears есть три способа подключения поведения внутри существующих приложений.

  • Крюк — это механизм, с помощью которого можно определить событие и уведомить зарегистрированных слушателей о том, когда и когда происходят события.

  • Контроллер Wrapper — Он расположен между TurboGears и Controller, так что можно расширить контроллер как декоратор. Таким образом, его можно подключить к любому стороннему контроллеру приложения.

  • Application Wrapper — похож на любое промежуточное ПО WSGI, но работает только в контексте TurboGears.

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

Контроллер Wrapper — Он расположен между TurboGears и Controller, так что можно расширить контроллер как декоратор. Таким образом, его можно подключить к любому стороннему контроллеру приложения.

Application Wrapper — похож на любое промежуточное ПО WSGI, но работает только в контексте TurboGears.

Здесь, в этой главе, мы обсудим, как использовать хуки внутри существующего приложения.

Крючки

Хуки — это события, зарегистрированные в файле конфигурации приложения app_cfg.py . Любой контроллер затем подключается к этим событиям декораторами событий.

Следующие хуки определены в TurboGears —

Sr.No. Крючки и описание
1

Запускать()

только для всего приложения, вызывается при запуске приложения.

2

неисправность()

только приложение, вызывается при выходе из приложения.

3

configure_new_app

новое приложение создано конфигуратором приложения.

4

before_config (приложение)

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

5

after_config (приложение)

только для всего приложения, вызывается после завершения настройки.

6

before_validate

Вызывается перед выполнением проверки

7

before_call

Вызывается после проверки, перед вызовом фактического метода контроллера.

8

before_render

Вызывается перед рендерингом шаблона контроллера. Выходное значение — возвращаемое значение контроллера.

9

after_render

Вызывается после окончания рендеринга шаблона контроллера.

Запускать()

только для всего приложения, вызывается при запуске приложения.

неисправность()

только приложение, вызывается при выходе из приложения.

configure_new_app

новое приложение создано конфигуратором приложения.

before_config (приложение)

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

after_config (приложение)

только для всего приложения, вызывается после завершения настройки.

before_validate

Вызывается перед выполнением проверки

before_call

Вызывается после проверки, перед вызовом фактического метода контроллера.

before_render

Вызывается перед рендерингом шаблона контроллера. Выходное значение — возвращаемое значение контроллера.

after_render

Вызывается после окончания рендеринга шаблона контроллера.

Зарегистрировать крюк

Чтобы зарегистрировать хук, создайте функции в app_cfg.py, а затем зарегистрируйте их, используя следующий код —

tg.hooks.register(hookane, function, controller)

В следующем коде хуки on_startup, on_shutdown и before_render зарегистрированы в app_cfg.py.

def on_startup():
   print 'hello, startup world'
   
def on_shutdown():
   print 'hello, shutdown world'
   
def before_render(remainder, params, output):
   print 'system wide before render'
   
# ... (base_config init code)
tg.hooks.register('startup', on_startup)
tg.hooks.register('shutdown', on_shutdown)
tg.hooks.register('before_render', before_render)

Хук before_render зарегистрирован с помощью функции контроллера в Rootcontroller. Добавьте следующий код в controllers \ root.py.

from tg.decorators import before_render

class RootController(BaseController):
   @expose('hello.templates.index')
   @before_render(before_render_cb)
	
   def index(self, *args, **kw):
      return dict(page = 'index')

Когда приложение обслуживается, в консоли отображается сообщение о запуске.

hello, startup world
Starting Standard HTTP server on http://127.0.0.1:8080

Когда в браузере вводится URL ‘/’, на консоли отображается сообщение, соответствующее хуку before_render.

system wide before render
Going to render {'page': 'index'}

TurboGears — Написание расширений

Расширения TurboGears идентифицируются пакетом tgext. * . Инструментарий Gearbox предоставляет команду tgext для создания примера расширения. Например —

gearbox tgext -n myextension

Другие необязательные параметры для этой команды:

  • —author — имя автора пакета.

  • —email — адрес электронной почты автора пакета.

  • —licence — лицензия, используемая для пакета. По умолчанию это MIT.

  • —description — Описание пакета.

  • —keywords — Пакет ключевых слов (по умолчанию: turbogears2.extension).

—author — имя автора пакета.

—email — адрес электронной почты автора пакета.

—licence — лицензия, используемая для пакета. По умолчанию это MIT.

—description — Описание пакета.

—keywords — Пакет ключевых слов (по умолчанию: turbogears2.extension).

Это создаст каталог tgext.myextension, который имеет простой пример расширения внутри.

Запустите setup.py внутри каталога —

Python setup.py install

Файл _init_.py внутри папки tgext / myextension содержит —

  • Функция Plugme — это точка входа в расширение.

  • Класс SetupExtension — здесь происходит инициализация расширения.

  • Функция On_startup — внутри класса есть хук, зарегистрированный в функции __call__ внутри класса.

Функция Plugme — это точка входа в расширение.

Класс SetupExtension — здесь происходит инициализация расширения.

Функция On_startup — внутри класса есть хук, зарегистрированный в функции __call__ внутри класса.

Краткая версия tgext \ myextension \ __ init__.py .

from tg import config
from tg import hooks
from tg.configuration import milestones

import logging
log = logging.getLogger('tgext.myextension')

def plugme(configurator, options = None):
   if options is None:
      options = {}
   log.info('Setting up tgext.myextension extension...')
   milestones.config_ready.register(SetupExtension(configurator))
   
   return dict(appid='tgext.myextension')
	
class SetupExtension(object):
   def __init__(self, configurator):
      self.configurator = configurator
      
   def __call__(self):
      log.info('>>> Public files path is %s' % config['paths']['static_files'])
      hooks.register('startup', self.on_startup)
      
   def echo_wrapper_factory(handler, config):
      def echo_wrapper(controller, environ, context):
         log.info('Serving: %s' % context.request.path)
         return handler(controller, environ, context)
      return echo_wrapper
      
   self.configurator.register_wrapper(echo_wrapper_factory)
   
   def on_startup(self):
      log.info('+ Application Running!')

После того, как расширение установлено, включите его, сделав следующие дополнения в файле конфигурации приложения app_cfg.py .

from tgext.myextension import plugme

plugme(base_config)

Если мы запускаем сервер с помощью команды сервера коробки передач, уведомление о недавно зарегистрированном расширении можно просмотреть на консоли следующим образом:

14:29:13,250 INFO [tgext.myextension] Setting up tgext.myextension extension...
14:29:13,453 INFO [tgext.myextension] >>> Public files path is c:\tghello\hello\hello\public
14:29:13,453 INFO [tgext.myextension] + Application Running!

Starting Standard HTTP server on http://127.0.0.1:8080

TurboGears — Сменные приложения

Если вашему расширению необходимо предоставить модели и контроллеры, вы, вероятно, захотите взглянуть на Pluggable Applications , которые предназначены для создания повторно используемых приложений Turbogears, которые можно подключать к другим приложениям для расширения их функций.

Используйте следующую команду gearbox для создания подключаемого приложения:

gearbox quickstart-pluggable plugtest

Эти подключаемые приложения могут определять свои собственные —

  • Контроллеры — которые будут автоматически монтироваться при удалении приложения.

  • Модели — которые будут доступны внутри и снаружи подключенного приложения.

  • Помощники — которые могут автоматически отображаться в объекте «H» в шаблоне приложения.

  • Bootstrapзапускается при вызове setup-app.

  • Статика — которая будет доступна по собственному личному пути.

Контроллеры — которые будут автоматически монтироваться при удалении приложения.

Модели — которые будут доступны внутри и снаружи подключенного приложения.

Помощники — которые могут автоматически отображаться в объекте «H» в шаблоне приложения.

Bootstrapзапускается при вызове setup-app.

Статика — которая будет доступна по собственному личному пути.

Установите это приложение plugtest и смонтируйте его, внеся следующие изменения в app_cfg.py .

from tgext.pluggable import plug
plug(base_config, plugtest)

TurboGears — RESTful приложения

REST означает RE презентационный Государственный перевод. REST — это архитектура, основанная на веб-стандартах и ​​использующая протокол HTTP для передачи данных. Он вращается вокруг ресурса, где каждый компонент является ресурсом, а доступ к ресурсу осуществляется с помощью общего интерфейса с использованием стандартных методов HTTP. REST был впервые представлен Роем ​​Филдингом в 2000 году .

Что такое RestController

RestController в TurboGears предоставляет механизм доступа к методу запроса, а не только к URL. Стандартное словосочетание HTTP включает в себя: GET, POST, PUT и DELETE. RestController поддерживает их, а также добавляет несколько ярлыков для рассылки URL-адресов, что делает отображение данных в виде форм и списков более удобным для пользователя.

Чтобы объяснить, как RESTful работает с TurboGears, мы собираемся определить простой веб-сервис, который предоставляет список студентов.

Код для модели студента приведен ниже —

модель \ student.py

# -* - coding: utf-8 -*-
from sqlalchemy import *

from sqlalchemy.orm import mapper, relation, relation, backref
from sqlalchemy import Table, ForeignKey, Column
from sqlalchemy.types import Integer, Unicode, DateTime
from hello.model import DeclarativeBase, metadata, DBSession
from datetime import datetime

class student(DeclarativeBase):
   __tablename__ = 'student'
   
   uid = Column(Integer, primary_key = True)
   name = Column(Unicode(20), nullable = False, default = '')
   city = Column(Unicode(20), nullable = False, default = '')
   address = Column(Unicode(100), nullable = False, default = '')
   pincode = Column(Unicode(10), nullable = False, default = '')

Теперь создайте контроллер на основе RestController и предоставьте функцию просмотра для вывода списка учеников в формате json.

Контроллеры \ student.py

from tg import RestController
from tg import expose
from hello import model
from hello.model import DBSession
from hello.model.student import student
from tg.decorators import with_trailing_slash

class StudentController(RestController):
   @expose('json')
   def get_all(self):
      students = DBSession.query(student).all()
      return dict(students=students)

Смонтируйте этот StudentController в RootController приложения, добавив следующие строки в root.py

from hello.controllers.student import StudentController

class RootController(BaseController):

   students = StudentController()

Перейдя по адресу http: // localhost: 8080 / student, он предоставит список наших студентов в формате json.

Мы используем метод post, чтобы определить, как мы сохраняем нашего ученика в базе данных. Этот метод вызывается всякий раз, когда к URL-адресу http: // localhost: 8080 / student выполняется запрос POST —

@expose('json')
def post(self, name, city, address, pincode):
   newstudent = student(name = name, city = city, address = address, pincode = pincode)
   DBSession.add(newstudent)
   DBSession.flush()
   return dict(student = newstudent)

Используя метод get_one () , мы можем отобразить один элемент из базы данных пользователю —

@expose('json')
def get_one(self, movie_id):
   newstudent = DBSession.query(student).get(uid)
   return dict(movie = movie)

PUT — метод, используемый для обновления существующей записи с использованием REST —

@expose('json')
def put(self, name = name, city = city, address =  address, pincode = pincode, **kw):
   newstudent = DBSession.query(student).get(name)
   newstudent.name = name
   newstudent.city = city
   newstudent.address = address
   newstudent.pincode = pincode
   return dict(student = newstudent)

Рабочая лошадка удаления прикреплена к методу post_delete. Здесь мы фактически удаляем запись из базы данных, а затем перенаправляем обратно на страницу листинга —

@expose('json')
def post_delete(self, uid, **kw):
   newstudent = DBSession.query(student).get(uid)
   DBSession.delete(newstudent)
   return dict(movie = newstudent.uid)

TurboGears — Развертывание

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

Apache с mod_wsgi

Mod_wsgi — это модуль Apache, разработанный Грэмом Дамплтоном. Он позволяет обслуживать программы WSGI с помощью веб-сервера Apache.

Во-первых, установите Apache 2.X для вашей платформы, если это еще не сделано. После установки Apache установите mod_wsgi. Создайте и активируйте виртуальную среду Python на сервере и установите на нем TurboGears.

Установите ваше приложение в директории приложения, затем создайте скрипт с именем app.wsgi .

Настройте установку Apache следующим образом:

<VirtualHost *:80>
   ServerName www.site1.com
   WSGIProcessGroup www.site1.com
   WSGIDaemonProcess www.site1.com user = <username> 
      group = www-data threads = 4 python-path = <pythonpath>
   WSGIScriptAlias myapp/app.wsgi
	
   #Serve static files directly without TurboGears
   Alias /images
   Alias /css
   Alias /js
   CustomLog
   ErrorLog
</VirtualHost>

Перезапустите Apache

Введите http://www.site1.com/ в браузере, чтобы получить доступ к приложению.

TurboGears под цирк и шоссет

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

TurboGears — GoogleAppEngine

Установите Google AppEngine SDK для Python по следующему URL-адресу — https: //cloud.google.coms

Установите Google AppEngine в своей системе. Затем откройте консоль разработчика Google и войдите в свою учетную запись Google — https://console.developers.google.com/start.

Создайте новый проект под названием mytgapp

Мытгапп Проект

Используя Google AppEngine Launcher, создайте новое приложение с именем mytgapp.

Новое приложение

Google App Engine Launcher

Следующие файлы будут созданы в указанном каталоге —

  • app.yaml
  • favicon.ico
  • index.yaml
  • main.py

По умолчанию созданное приложение использует платформу Webapp2. Чтобы удалить эту зависимость, отредактируйте файл app.yaml и удалите следующую часть:

libraries:
   - name: webapp2
   version: "2.5.2"

Создайте временную виртуальную среду в каталоге с именем mytgapp и установите TurboGears. Создайте в нем приложение TurboGears. Теперь мы можем продолжить редактирование файла main.py, который запускается AppEngine, чтобы запустить наше приложение и фактически написать там приложение TurboGears.

Добавьте следующее содержимое в main.py

import os
import site
site.addsitedir(os.path.join(os.path.dirname(__file__), 'packages'))
from tg import expose, TGController, AppConfig

class RootController(TGController):
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
		
config = AppConfig(minimal = True, root_controller = RootController())
app = config.make_wsgi_app()

Теперь запустите приложение из AppEngine Launcher и нажмите кнопку обзора, чтобы убедиться, что приложение работает на локальном хосте.

Мы уже создали проект с именем mytgapp в консоли разработчика. Теперь нажмите кнопку развертывания в Launcher. После завершения процесса развертывания посетите веб-сайт http://mytgapp.appspot.com/, чтобы просмотреть наше приложение в Интернете.