Turbogears-퀵 가이드
웹 프레임 워크 란?
웹 애플리케이션 프레임 워크 또는 단순히 웹 프레임 워크는 라이브러리 및 모듈 모음을 나타내며,이를 통해 웹 애플리케이션 개발자는 프로토콜, 스레드 관리 등과 같은 낮은 수준의 세부 정보에 대해 신경 쓰지 않고도 애플리케이션을 작성할 수 있습니다.
TurboGears는 무엇입니까?
TurboGears는 Python으로 작성된 웹 애플리케이션 프레임 워크입니다. 원래 Kevin Dangoor가 2005 년에 만든 최신 버전 TurboGears (버전 2.3.7)는 Mark Ramm과 Florent Aide가 이끄는 개발자 그룹이 관리합니다.
TurboGears는 Rails, Django, Struts 등과 같은 대부분의 최신 웹 프레임 워크처럼 Model-View-Controller 패러다임을 따릅니다.
모델보기 컨트롤러
MVC는 웹 애플리케이션 개발을위한 소프트웨어 디자인 패턴입니다. Model View Controller 패턴은 세 부분으로 구성됩니다.
Model − 패턴의 가장 낮은 수준은 데이터 유지를 담당합니다.
View − 이것은 사용자에게 데이터의 전체 또는 일부를 표시하는 책임이 있습니다.
Controller − 모델과 뷰 간의 상호 작용을 제어하는 소프트웨어 코드.
MVC는 사용자 인터페이스 계층에서 응용 프로그램 논리를 분리하고 문제 분리를 지원하므로 널리 사용됩니다. 여기서 컨트롤러는 애플리케이션에 대한 모든 요청을 수신 한 다음 모델과 함께 작동하여 뷰에 필요한 데이터를 준비합니다. 그런 다음 View는 컨트롤러가 준비한 데이터를 사용하여 최종 표현 가능한 응답을 생성합니다. MVC 추상화는 다음과 같이 그래픽으로 표현할 수 있습니다.
모델
모델은 애플리케이션의 데이터를 관리합니다. 뷰의 요청에 응답하고 컨트롤러의 명령에 응답하여 자체 업데이트합니다.
보기
데이터를 표시하기로 한 컨트롤러의 결정에 의해 트리거되는 특정 형식의 데이터 표시. AJAX 기술과 통합하기 매우 쉬운 스크립트 기반 템플릿 시스템입니다.
컨트롤러
컨트롤러는 사용자 입력에 응답하고 데이터 모델 개체에 대한 상호 작용을 수행합니다. 컨트롤러는 입력을 받고 입력을 확인한 다음 데이터 모델의 상태를 수정하는 비즈니스 작업을 수행합니다.
TurboGears는 많은 라이브러리와 도구를 기반으로 구축되었습니다. 이러한 도구는 TurboGears의 다른 버전간에 변경되었습니다. 현재 버전 (ver 2.3.7)의 구성 요소는 다음과 같습니다.
SQLAlchemy
Python 코드에 대한 ORM (Object Relationship Mapping)을 제공하는 오픈 소스 SQL 키트입니다.
겐시
이 템플릿 엔진은 TG 애플리케이션의 프런트 엔드를 구성하는 데 사용됩니다. 웹 템플릿 시스템은 템플릿을 특정 데이터 소스와 결합하여 동적 웹 페이지를 렌더링합니다.
ToscaWidgets
서버 측 컨트롤을 사용하여 HTML 양식을 생성하기위한 위젯 라이브러리입니다. Tosca는 JavaScript 위젯 및 툴킷과 연결하는 미들웨어 역할도합니다.
변속 장치
프로젝트 및 서버 TurboGears 애플리케이션을 관리하는 명령 세트를 제공합니다. TurboGears 애플리케이션은 모든 WSGI 호환 웹 서버에 배포 할 수 있습니다.
WSGI (Web Server Gateway Interface)는 Python 웹 애플리케이션 개발의 표준으로 채택되었습니다. WSGI는 웹 서버와 웹 응용 프로그램 간의 범용 인터페이스 사양입니다. wsgiref 패키지는 WSGI의 참조 구현입니다. 웹 TurboGears 웹 프레임 워크에 WSGI 지원을 추가하는 데 사용됩니다. 이 패키지의 simple_server 모듈은 WSGI 응용 프로그램을 제공하는 간단한 HTTP 서버를 구현합니다. 이 튜토리얼에서 개발 된 애플리케이션을 테스트하는 데 사용할 것입니다.
전제 조건
Python 2.6 이상. TurboGears의 이전 버전은 Python 3.X와 호환되지 않았습니다. 최신 버전은 Python 3.X에서 잘 작동한다고 주장합니다. 그러나 TurboGears의 공식 문서는 여전히 Python 2.7 환경을 기반으로합니다.
다음 명령 installs virtualenv −
pip install virtualenv
이 명령에는 administrator특권. 더하다sudo before pipLinux / 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
이제 준비가되었습니다 install TurboGears이 환경에서. TurboGears의 최소 설치는 다음 명령으로 수행됩니다.
pip install TurboGears2
위의 명령은 시스템 전체 설치를 위해 가상 환경없이 직접 실행할 수 있습니다.
개발 도구와 함께 TurboGears를 설치하려면 다음 명령을 사용하십시오.
pip install tg.devtools
TurboGears에는 단일 파일 응용 프로그램을 빠르게 만들 수있는 최소 모드가 있습니다. 최소한의 종속성으로 간단한 예제와 서비스를 빠르게 구축 할 수 있습니다.
TG 애플리케이션의 애플리케이션 클래스는 다음에서 상속됩니다. TGController수업. 이 클래스의 메서드는 다음에서 액세스 할 수 있습니다.@expose 데코레이터 from 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()
이는 우리의 응용 프로그램이 localhost의 포트 번호 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.devtoolsof TurboGears에는 Gearbox가 포함되어 있습니다. 더 복잡한 TG 프로젝트를 관리하는 데 유용한 명령 세트입니다. 전체 스택 프로젝트는 다음 Gearbox 명령으로 빠르게 생성 할 수 있습니다.
gearbox quickstart HelloWorld
그러면 다음과 같은 프로젝트가 생성됩니다. HelloWorld.
TurboGears 프로젝트에는 다음 디렉토리가 포함되어 있습니다.
Config − 프로젝트 설정 및 구성이 의존하는 곳
Controllers − 모든 프로젝트 컨트롤러, 웹 애플리케이션 로직
i018n − 지원되는 언어에 대한 번역 파일
Lib − 유틸리티 파이썬 함수 및 클래스
Model − 데이터베이스 모델
Public Static Files − CSS, JavaScript 및 이미지
Templates − 컨트롤러에 의해 노출 된 템플릿.
Tests − 완료된 테스트 세트.
Websetup − 애플리케이션 설정시 실행할 기능.
프로젝트를 설치하는 방법
이제이 프로젝트를 설치해야합니다. ㅏsetup.py프로젝트의 기본 디렉토리에 이미 제공되어 있습니다. 이 스크립트가 실행되면 프로젝트 종속성이 설치됩니다.
Python setup.py develop
기본적으로 프로젝트 설정시 다음 종속성이 설치됩니다.
- Beaker
- Genshi
- zope.sqlalchemy
- sqlalchemy
- alembic
- repoze.who
- tw2.forms
- tgext.admin ≥ 0.6.1
- WebHelpers2
- babel
설치 후 셸에서 다음 명령을 실행하여 개발 서버에서 프로젝트 서비스를 시작하십시오.
Gearbox serve –reload –debug
위에서 언급 한 명령을 따라 미리 빌드 된 예제 프로젝트를 제공합니다. 열다http://localhost:8080브라우저에서. 이 기성품 샘플 애플리케이션은 TurboGears 프레임 워크 자체에 대한 간략한 소개를 제공합니다.
이 Hello 프로젝트에서 기본 컨트롤러는 controllers 디렉토리에 다음과 같이 생성됩니다. Hello/hello/controllers.root.py. 하자modify 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() 데코레이터 첨부 /sayHello그것의 URL. 이 함수는 URL에서 이름을 매개 변수로 허용하도록 설계되었습니다.
'기어 박스 서브'명령어를 통해 서버 시작 후 http://localhost:8080. 다음 URL을 입력해도 브라우저에 Hello World 메시지가 표시됩니다.
http://localhost:8080/
http://localhost:8080/index
이러한 모든 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 folder 신청의.
그 코드는 다음과 같습니다-
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 메서드로 디스패치합니다.
HTML 콘텐츠가 브라우저에 반환 될 수 있지만 이벤트는 고급 출력을 위해 항상 템플릿 엔진을 사용하는 것이 좋습니다. 기어 박스에 의해 '빠른 시작'된 풀 스택 프로젝트에서 Genshi는 기본 템플릿 렌더러로 활성화됩니다. 그러나 최소한의 애플리케이션에서는 Genshi (또는 jinja와 같은 다른 템플릿 엔진)를 설치하고 활성화해야합니다. Genshi 템플릿 엔진은 순수한 xhtml로 템플릿을 작성하고 컴파일 타임에 문제를 감지하고 깨진 페이지를 제공하지 않도록 유효성을 검사합니다.
템플릿은 점 표기법을 사용하여 참조됩니다. Hello 프로젝트에서는 템플릿 웹 페이지를 저장하기위한 템플릿 디렉토리가 제공됩니다. 그 후sample.html 로 언급됩니다 hello.templates.sample(언급되지 않은 확장). TurboGears는 노출 데코레이터를 통해이 템플릿을 렌더링하여 컨트롤러 메서드를tg.render_template() 함수.
노출 된 컨트롤러 함수는 Python 사전 객체를 반환합니다. 이 사전 개체는 연결된 템플릿에 차례로 전달됩니다. 템플릿의 자리 표시자는 사전 값으로 채워집니다.
먼저 일반 html 스크립트로 웹 페이지를 표시하겠습니다. 노출 된 컨트롤러는null dictionary object 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 양식은 양식 데이터를 보내는 데 사용합니다.
Http 프로토콜은 월드 와이드 웹에서 데이터 통신의 기초입니다. 지정된 URL에서 데이터를 검색하는 여러 방법이이 프로토콜에 정의되어 있습니다. 다음 표는 다양한 http 방법을 요약 한 것입니다.
Sr. 아니. | HTTP 방법 및 설명 |
---|---|
1 | GET 암호화되지 않은 형식의 데이터를 서버에 보냅니다. 가장 일반적인 방법. |
2 | HEAD GET과 동일하지만 응답 본문이 없음 |
삼 | POST HTML 양식 데이터를 서버로 보내는 데 사용됩니다. POST 방식으로 수신 된 데이터는 서버에서 캐시되지 않습니다. |
4 | PUT 대상 리소스의 모든 현재 표현을 업로드 된 콘텐츠로 바꿉니다. |
5 | DELETE 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>
이 양식에 입력 된 데이터는 ‘/login’ URL. 이제 컨트롤러 함수를 만듭니다.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 template engine 다음 출력을 생성하려면-
POST 방법
HTML 양식이 POST 메소드를 사용하여 URL in action 속성으로 데이터를 발송할 때 양식 데이터는 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 다음 출력을 렌더링합니다-
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에는 많은 지시문이 정의되어 있습니다. 다음 목록은 Genshi 지시문을 열거합니다-
- py:if
- py:choose
- py:for
- py:def
- py:match
- py:with
- py:replace
- py:content
- py:attrs
- py:strip
조건부 섹션
Genshi는 콘텐츠의 조건부 렌더링을위한 두 가지 지시문 (py : if 및 py : choose)을 제공합니다.
py : if
이 지시문 요소의 내용은 if clause참으로 평가됩니다. 템플릿 컨텍스트의 데이터가{‘foo’:True, ‘bar’:’Hello’}, 다음 지시문-
<div>
<b py:if = "foo">${bar}</b>
</div>
결과적으로
Hello
그러나이 출력은 다음과 같은 경우 렌더링되지 않습니다. ‘foo’ is set to False.
이 지시문은 요소로도 사용할 수 있습니다. 이 경우<py:if> 해당에 의해 폐쇄되어야합니다 </py:if>
<div>
<py:if test = "foo">
<b>${bar}</b>
</py:if>
</div>
py : choose
고급 조건부 처리는 다음을 사용하여 가능합니다. py:choose 함께 py:when 과 py:otherwise지시. 이 기능은 다음과 유사합니다.switch – case 건설하다 C/C++.
표현 py:choose 지시문은 다음으로 식별되는 다른 값으로 확인됩니다. py:when대안 및 해당 콘텐츠가 렌더링됩니다. 기본 대안은 다음과 같은 형식으로 제공 될 수 있습니다.py:otherwise 지령.
<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 양식은 데이터를 / marks URL에 게시합니다. 그만큼marks() 함수는 사전 객체 형태의 마크와 결과를 다음으로 리디렉션합니다. total.html주형. 조건부 표시result 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 다음 출력을 렌더링합니다-
py : for
py : for 지시문의 요소는 반복 가능한 각 항목 (일반적으로 Python List 객체)에 대해 반복됩니다. 만약items = [1,2,3] 템플릿 컨텍스트에 존재하는 경우 py : for 지시문을 따라 반복 할 수 있습니다.
<ul>
<li py:for = "item in items">${item}</li>
</ul>
다음 출력이 렌더링됩니다-
1
2
3
다음 예제는 py : for 지시문을 사용하여 total.html 템플릿에서 렌더링 된 HTML 양식 데이터를 보여줍니다.
<py:for each = "item in items">
<li>${item}</li>
</py:for>
HTML 양식 스크립트
<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 브라우저에서.
위의 양식이 제출되면 다음 출력이 브라우저에 표시됩니다.
py : def
이 지시문은 매크로를 만드는 데 사용됩니다. 매크로는 재사용 가능한 템플릿 코드 스 니펫입니다. 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
브라우저에 다음 URL을 입력하여 macro () 컨트롤러를 호출합니다.
http://localhost:8080/macro
다음 출력은 브라우저에서 렌더링됩니다-
py : with
이 지시문을 사용하면 지역 변수에 표현식을 할당 할 수 있습니다. 이러한 지역 변수는 내부 표현을 덜 장황하고 효율적으로 만듭니다.
템플릿에 대한 컨텍스트 데이터에 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 () 컨트롤러는 이름, phy 및 수학 키가있는 dict 객체를 반환합니다.
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 템플릿은 py : with 지시문을 사용하여 phy 및 maths 키의 값을 추가합니다.
<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: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>
현재 문서에서 포함 태그를 사용하여 다른 XML 문서 (특히 HTML 문서)의 내용을 포함 할 수 있습니다. 이러한 포함을 활성화하려면 HTML 문서의 루트 요소에서 XInclude 네임 스페이스를 선언해야합니다.
<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.html을 노출하는 include () 컨트롤러를 포함합니다.
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의 내용이 추가됩니다. 다음은 templates \ include.html의 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>
다음은 templates \ heading.html 코드입니다.
<html>
<head>
<title>TurboGears Templating Example</title>
</head>
<body>
<h1>This is page Header</h1>
</body>
</html>
다음은 templates \ 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>
서버를 시작하기 전에 템플릿 폴더에 heading.html, main.html 및 footer.html이 있는지 확인하십시오. 시작하다http://localhost:8082/refinclude 브라우저에서 다음 출력을 얻습니다.
그만큼 @expose()데코레이터는 기본적으로 html 콘텐츠를 렌더링합니다. 그러나 이것은 다음과 같이 설정할 수 있습니다.json content type. TurboGears는 다음을 통해 json 렌더링을 지원합니다.tg.jsonify.JSONEncoder (**kwargs)수업. json 데이터를 렌더링하려면 json을 콘텐츠 유형으로 전달하여 데코레이터를 노출하면됩니다.
@expose('json')
def jsondata(self, **kwargs):
return dict(hello = 'World')
브라우저에 '/ jsondata'URL을 입력하면-
{"hello": "World"}
jsonp 렌더링
jsonp는 패딩이있는 json을 나타냅니다. 컨트롤러가 반환하는 모든 값을 함수 인수로 제공하는 자바 스크립트 함수 호출과 함께 애플리케이션 / 자바 스크립트 응답을 제공한다는 점을 제외하면 json 출력과 유사하게 작동합니다.
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"});
때로는 웹 응용 프로그램에 둘 이상의 수준이있는 URL 구조가 필요할 수 있습니다. TurboGears는 객체 계층 구조를 탐색하여 요청을 처리 할 수있는 적절한 방법을 찾을 수 있습니다.
기어 박스가있는 '빠른 시작'프로젝트는 프로젝트의 lib 폴더에 BaseController 클래스가 있습니다. 'Hello / hello / lib / base.py'로 제공됩니다. 모든 하위 컨트롤러의 기본 클래스 역할을합니다. 애플리케이션에 하위 수준의 URL을 추가하려면 BaseController에서 파생 된 BlogController라는 하위 클래스를 디자인합니다.
이 BlogController에는 index () 및 post ()의 두 가지 컨트롤러 함수가 있습니다. 둘 다 각각 blog.html 및 post.html 템플릿을 노출하도록 설계되었습니다.
Note −이 템플릿은 하위 폴더 안에 있습니다 − 템플릿 / 블로그
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/입력되면 BlogController 클래스 내의 index () 컨트롤러 함수에 매핑됩니다. 비슷하게,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 입력하면 다음과 같은 출력이 생성됩니다.
웹 애플리케이션의 가장 필수적인 측면 중 하나는 사용자에게 사용자 인터페이스를 제공하는 것입니다. HTML은 인터페이스를 디자인하는 데 사용되는 <form> 태그를 제공합니다. 텍스트 입력, 라디오, 선택 등 Form의 요소를 적절하게 사용할 수 있습니다. 사용자가 입력 한 데이터는 GET 또는 POST 방식으로 Http 요청 메시지 형태로 서버 측 스크립트에 제출됩니다.
서버 측 스크립트는 http 요청 데이터에서 양식 요소를 다시 작성해야합니다. 따라서이 효과에서 양식 요소는 HTML에서 한 번, 서버 측 스크립트에서 다시 두 번 정의되어야합니다.
HTML 양식 사용의 또 다른 단점은 양식 요소를 동적으로 렌더링하는 것이 어렵다는 것입니다 (불가능하지는 않지만). HTML 자체는 사용자 입력의 유효성을 검사하는 방법을 제공하지 않습니다.
ToscaWidgets2
TurboGears는 유연한 양식 렌더링 및 유효성 검사 라이브러리 인 ToscaWidgets2를 사용합니다. ToscaWidgets를 사용하여 Python 스크립트에서 양식 필드를 정의하고 HTML 템플릿을 사용하여 렌더링 할 수 있습니다. tw2 필드에 유효성 검사를 적용 할 수도 있습니다.
ToscaWidgets 라이브러리는 많은 모듈의 모음입니다. 몇 가지 중요한 모듈은 다음과 같습니다.
tw2.core− 핵심 기능을 제공합니다. 이 모듈의 위젯은 최종 사용자가 사용할 수 없습니다.
tw2.forms− 이것은 기본 양식 라이브러리입니다. 여기에는 필드, 필드 세트 및 양식에 대한 위젯이 포함되어 있습니다.
tw2.dynforms − 여기에는 동적 양식 기능이 포함되어 있습니다.
tw2.sqla − SQLAlchemy 데이터베이스를위한 인터페이스입니다.
tw2.forms
사용자 지정 양식의 기본 역할을하는 Form 클래스가 포함되어 있습니다. 2 열 테이블의 필드를 렌더링하는 데 유용한 TableForm 클래스가 있습니다. ListForm은 순서가 지정되지 않은 목록으로 필드를 표시합니다.
Sr. 아니. | 필드 및 설명 |
---|---|
1 | TextField 한 줄 텍스트 입력 필드 |
2 | TextArea 여러 줄 텍스트 입력 필드 |
삼 | CheckBox 레이블이있는 체크 가능한 직사각형 상자를 제공합니다. |
4 | CheckBoxList 다중 선택 가능한 그룹 pf 확인란 |
5 | RadioButton 선택 / 선택 취소를위한 토글 버튼 |
6 | RadioButtonList 상호 배타적 인 라디오 버튼 그룹 |
7 | PasswordField Textfield와 유사하지만 입력 키가 표시되지 않습니다. |
8 | CalendarDatePicker 사용자가 날짜를 선택할 수 있습니다. |
9 | SubmitButton 양식 제출 버튼 |
10 | ImageButton 상단에 이미지가있는 클릭 가능한 버튼 |
11 | SingleSelectField 목록에서 단일 항목을 선택할 수 있습니다. |
12 | MultipleSelectField 목록에서 여러 항목을 선택할 수 있습니다. |
13 | FileField 파일 업로드 필드 |
14 | EmailField 이메일 입력 필드 |
15 | URLField URL을 입력하기위한 입력 필드 |
16 | NumberField 숫자 스핀 박스 |
17 | 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기본 클래스. 필요한 위젯은 레이아웃 개체 내에 배치됩니다. 이 예에서TableLayout사용. 위젯은 2 열 테이블로 렌더링됩니다. 첫 번째 열에는 캡션이 표시되고 두 번째 열에는 입력 또는 선택 필드가 표시됩니다.
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 객체를 포함합니다. 각 옵션에 대한 라디오 버튼이 렌더링됩니다. 기본 선택은 value 매개 변수로 지정됩니다.
twf.RadioButtonList(options = ["option1","option2"],value = option1)
CheckBoxList는 목록의 각 옵션에 대한 확인란을 렌더링합니다.
twf.CheckBoxList(options = [option1, option2, option3])
드롭 다운 목록은이 ToscaWidgets 라이브러리에서 SingleSelectfield로 호출됩니다. 옵션 매개 변수에 해당하는 List 객체의 항목은 드롭 다운 목록을 형성합니다. 보이는 캡션은 prompt_text 매개 변수의 값으로 설정됩니다.
twf.SingleSelectField(prompt_text = 'text', options=['item1', 'item2', 'item3'])
기본적으로 양식에는 캡션이 '저장'인 제출 단추가 표시됩니다. 다른 캡션을 표시하려면 SubmitButton 개체를 만들고 값 매개 변수로 지정합니다.
twf.SubmitButton(value = 'Submit')
양식은 양식의 조치 매개 변수 값으로 지정된 URL에 제출됩니다. 기본적으로 양식 데이터는 http POST 메소드로 제출됩니다.
action = 'URL'
다음 코드에서 AdmissionForm이라는 폼은 위에서 설명한 위젯을 사용하여 디자인되었습니다. 이 코드를 RootController 클래스 앞에 root.py에 추가하십시오.
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 클래스에는 stipulated/save_form액션 URL로. 따라서 추가save_form() RootController의 함수.
@expose()
def save_movie(self, **kw):
return str(kw)
서버가 실행 중인지 확인합니다 (기어 박스 서비스 사용). 시작하다http://localhost:8080/twform 브라우저에서.
제출 버튼을 누르면이 데이터가 save_form() URL : 사전 객체의 형태로 양식 데이터를 표시합니다.
{
'EmailID': u'[email protected]',
'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'
}
좋은 Forms 위젯 라이브러리에는 입력 유효성 검사 기능이 있어야합니다. 예를 들어, 사용자는 유효성 검사를 위해 다른 프로그래밍 방식 (예 : JavaScript 함수)에 의존하지 않고 필수 필드에 데이터를 입력하거나 이메일 필드에 유효한 이메일이 포함되어 있는지 확인해야합니다.
ToscaWidgets Forms Library의 초기 버전은 유효성 검사 지원을 위해 FormEncode 모듈에 의존하는 데 사용되었습니다. ToscaWidgets2에는 이제 tw2.core 모듈에서 사용 가능한 기본 제공 유효성 검사 지원이 있습니다. 그러나 FormEncode 유효성 검사 기술을 사용할 수는 있습니다.
ToscaWidgets 양식을 검증하기 위해 @validate 데코레이터가 사용됩니다.
@validate(form, error_handler, validators)
그만큼 ’form’ 유효성을 검사 할 ToscaWidgets 양식 개체입니다.
그만큼 ‘error-handler’ 양식 오류를 처리하는 데 사용되는 컨트롤러 메서드입니다.
그만큼 ‘validators’ FormEncode 유효성 검사기를 포함하는 사전 개체입니다.
유효성 검사기 유형
tw2.core 모듈에는 다른 유효성 검사기가 상속되는 유효성 검사기 클래스가 포함되어 있습니다. 이를 기반으로 사용자 정의 유효성 검사기를 설계하는 것도 가능합니다. 중요한 유효성 검사기 중 일부는 아래에 설명되어 있습니다.
LengthValidator− 값이 규정 된 길이인지 확인합니다. 최소 및 최대 한계는 최소 및 최대 매개 변수로 정의됩니다. 최소 및 최대 길이 이하의 사용자 지정 메시지는 tooshort 및 toolong 매개 변수로 지정할 수 있습니다.
tw2.core.LengthValidator(min = minval, max = maxval,
msgs = { 'tooshort': (‘message for short length’),
'toolong': (‘message for long length)})
RangeValidator− 일반적으로 RangeField와 함께 사용됩니다. 최소 및 최대 한계 내에서 숫자 필드의 값을 검증하는 것이 유용합니다. 너무 짧고 툴롱 매개 변수에 대한 메시지는 사용자 정의 할 수 있습니다.
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는 확장 가능한 CompoundValidator의 하위 클래스 인 Any 및 All 유효성 검사기를 제공합니다.
TurboGears는 눈에 거슬리지 않는 방식으로 사용자에게 정보를 알릴 수있는 매우 편리한 메시징 시스템을 제공합니다. tg 모듈의 TGFlash 클래스는 일반 쿠키에 저장된 플래싱 메시지를 지원합니다. 이 클래스는 JavaScript를 통해 클라이언트 측뿐만 아니라 서버 측에서 플래시 메시지 가져 오기를 지원합니다.
그만큼 render()Python 자체에서 사용되는 TGFlash 클래스의 메서드는 템플릿에서 호출하여 플래시 메시지를 렌더링 할 수 있습니다. JavaScript에서 사용하는 경우 WebFlash 개체를 제공합니다. 그것은 노출payload() 과 render() 현재 플래시 메시지를 가져 와서 JavaScript에서 렌더링하는 메소드.
TurboGears 프로젝트가 'quickstart'를 사용하여 생성되면 Master.html 템플릿이 있습니다. 여기에는 해당 플래시 개체의 변수 정의가 포함됩니다. 컨트롤러에서받은이 플래시 메시지의 내용은이 템플릿에서 표시된 자리 표시자를 대체합니다.
<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 메시지는 다음을 사용하여 쿠키 (기본 이름은 webflash)에 저장됩니다. tg.flash()방법. 그런 다음 메시지 및 상태 매개 변수가 전달됩니다.
tg.flash('Message', 'status')
flash라는 메서드가 리디렉션을 수행하면 리디렉션 된 페이지 내에 플래시가 표시됩니다. 메서드가 템플릿을 직접 노출하는 경우 템플릿 자체 내부에 플래시가 표시됩니다.
상태 코드에 CSS 스타일을 적용하여 플래시 메시지의 모양을 사용자 지정할 수 있습니다. '빠른 시작'프로젝트에는 스타일 시트 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')}" />
모든 플래시 메시지 지원의 구성은 TGFlash 객체의 configure () 메서드 또는 app_cfg.py (config 폴더에 있음)에 대한 매개 변수를 설정하여 수행 할 수 있습니다. 구성 가능한 매개 변수는 다음과 같습니다.
Sr. 아니. | 매개 변수 및 설명 |
---|---|
1 | flash.cookie_name 플래시 메시지를 저장하는 데 사용되는 쿠키의 이름입니다. 기본값은webflash. |
2 | flash.default_status 지정되지 않은 경우 기본 메시지 상태 (기본적으로 확인) |
삼 | flash.template 로 사용 flash template 렌더링 할 때. |
4 | flash.allow_html 턴 on/off escaping in flash messages, 기본적으로 HTML은 허용되지 않습니다. |
5 | flash.js_call JavaScript에서 플래시를 표시 할 때 실행되는 JavaScript 코드입니다. 기본값은webflash.render() |
6 | flash.js_template string.Template 플래시 메시지에 대한 완전한 JavaScript 지원을 대체하는 데 사용되는 인스턴스입니다. |
pop_payload() − 기능 fetches current flash message, status및 관련 정보. 플래시 메시지를 받으면 쿠키가 삭제됩니다.
render(container_id, use_js=True) − 템플릿 내에서 플래시 메시지를 렌더링하거나 자바 스크립트 지원을 제공합니다.
container_id 메시지가 표시되는 DIV이고 use_js는 플래시를 HTML로 렌더링하거나 자바 스크립트 사용을 위해 전환합니다.
status − 현재 플래시 상태 만 가져오고 플래시 상태를 가져 오면 쿠키가 삭제됩니다.
message − 현재 플래시 메시지 만 가져 오기, 플래시 메시지 가져 오기는 쿠키를 삭제합니다.
간단한 플래시 메시지를 만드는 방법?
다음 예제에서는 루트 컨트롤러 클래스에 flash () 메서드가 제공됩니다. 노출 된 템플릿 flash.html로 렌더링되는 flash () 메시지를 호출합니다.
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의 세션 데이터는 파일 시스템, 데이터베이스 또는 해시 된 쿠키 값에 의해 지원 될 수 있습니다. 소량의 세션 데이터는 일반적으로 쿠키에 보관되지만 더 많은 양의 세션 데이터에는 MemCache가 사용됩니다.
MemCache는 시스템 수준 데몬입니다. 캐시 된 데이터에 대한 빠른 액세스를 제공하며 확장 성이 뛰어납니다. 그러나 보안 서버에서만 사용하기위한 것이므로 sysadmin에서 유지 관리하고 보안을 유지해야합니다.
세션 관리의 비커
TurboGears는 세션 관리를 위해 Beaker를 사용합니다. 기어 박스로 빠른 시작하는 프로젝트는 기본적으로 해시 된 쿠키를 사용하여 세션 데이터를 저장하도록 구성됩니다.
클라이언트가 연결할 때마다 세션 미들웨어 (Beaker)는 구성 파일에 정의 된 쿠키 이름을 사용하여 쿠키를 검사합니다. 쿠키가 발견되지 않으면 브라우저에 설정됩니다. 이후의 모든 방문에서 미들웨어는 쿠키를 찾아 사용합니다.
세션 관리를 활성화하려면 다음 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는 두 가지 유형의 캐싱 기술을 제공합니다.
Whole-page Caching
HTTP 프로토콜 수준에서 작동하여 사용자의 브라우저 또는 중간 프록시 서버 (예 : Squid)가 요청을 가로 채서 파일의 캐시 된 복사본을 반환하도록하여 서버에 대한 전체 요청을 방지합니다.
Application-level Caching
이는 애플리케이션 서버 내에서 작동하여 계산 된 값 (종종 복잡한 데이터베이스 쿼리의 결과)을 캐시하므로 향후 요청에서 값을 다시 계산할 필요가 없습니다. 웹 애플리케이션의 경우 애플리케이션 수준 캐싱은 복잡한 쿼리의 결과를 캐시하는 유연한 방법을 제공하므로 주어진 컨트롤러 메서드의 총로드를 몇 가지 사용자 별 또는 사례 별 쿼리와 템플릿의 렌더링 오버 헤드로 줄일 수 있습니다. .
애플리케이션 수준 캐싱
앞서 언급했듯이 '빠른 시작'TurboGears 프로젝트는 캐싱 지원을 위해 Beaker 패키지를 활성화하도록 구성됩니다. Beaker는 캐시 스토리지에 사용되는 다음 백엔드를 지원합니다.
memory− 프로세스 별 저장에 사용됩니다. 매우 빠릅니다.
filesystem − 프로세스 별 저장 및 다중 프로세스.
DBM database − 프로세스 별, 다중 프로세스, 상당히 빠름.
SQLAlchemy database− 데이터베이스 서버 당 스토리지. 위에 주어진 옵션에 비해 느립니다.
Memcached − 다중 서버 메모리 기반 캐시.
컨트롤러 캐싱
빠른 컨트롤러 캐싱을 위해 cached()데코레이터를 사용할 수 있습니다. 요청의 다양한 매개 변수에 따라 전체 컨트롤러 본문이 캐시됩니다. 정의tg.decorators.cached() 데코레이터는 다음과 같습니다
tg.decorators.cached(key, expire, type,
query-args, cache_headers, invalidate_on_startup, cache_response)
매개 변수에 대한 설명은 다음과 같습니다.
Sr. 아니. | 매개 변수 및 설명 |
---|---|
1 | key 캐시 키를 생성하는 데 사용되는 컨트롤러 매개 변수를 지정합니다. |
2 | expire 캐시가 만료되기까지의 시간 (초), 기본값은 "never"입니다. |
삼 | Type dbm, 메모리, 파일, memcached 또는 없음. |
4 | cache_headers 응답 헤더를 나타내는 헤더 이름의 튜플입니다. |
5 | invalidate_on_startup True이면 응용 프로그램이 시작되거나 다시 시작될 때마다 캐시가 무효화됩니다. |
6 | 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는 다음 키를 받아들이는 사전입니다-
key − 캐시 키. Default: 없음.
expire − 캐시가 살아 있어야하는 기간. Default: 만료되지 않음
type − 메모리, dbm, memcached. Default: dbm.
다음 예제는 템플릿 캐싱을 보여줍니다-
@expose(hello.templates.user')
def user(self, username):
return dict(user = username, tg_cache = dict(key = user, expire = 900))
TurboGears 애플리케이션에서 SQL을 사용하여 모든 관계형 데이터베이스에서 CRUD 작업을 수행 할 수 있지만 SQLAlchemy를 사용하는 것이 좋습니다. Python 툴킷은 애플리케이션 개발자에게 SQL의 모든 기능과 유연성을 제공하는 강력한 개체 관계 매퍼입니다. SQLAlchemy를 통한 SQL 기반 데이터베이스 지원 외에도 TurboGears는 Ming을 통해 MongoDB 데이터베이스를 지원합니다. 이 섹션에서는 SQLAlchemy의 기능에 대해 설명합니다.
ORM (Object Relational Mapping)이란 무엇입니까?
대부분의 프로그래밍 언어 플랫폼은 객체 지향입니다. 반면에 RDBMS 서버의 데이터는 테이블로 저장됩니다. 개체 관계 매핑은 개체 매개 변수를 기본 RDBMS 테이블 구조에 매핑하는 기술입니다. ORM API는 원시 SQL 문을 작성하지 않고도 CRUD 작업을 수행하는 방법을 제공합니다.
Gearbox 툴킷에서 'quickstart'명령을 사용하여 TurboGears 프로젝트를 생성 할 때 SQLAlchemy 지원은 기본적으로 다음 구성 설정에 의해 활성화됩니다.
config['use_sqlalchemy'] = True
config['sqlalchemy.url'] = 'sqlite:///devdata.db'
'빠른 시작'프로젝트는 그 안에 모델 패키지도 생성합니다. 예를 들어 'Hello'프로젝트에는 Hello \ hello \ model이 있습니다. 이 패키지에는 다음 파일이 생성됩니다.
__init__.py− 여기에서 데이터베이스 액세스가 설정됩니다. 애플리케이션의 모델 개체를이 모듈로 가져옵니다. 또한 DBSession (전역 세션 관리자)과 모든 모델 클래스의 기본 클래스 인 DeclarativeBase도 있습니다.
auth.py− 여기에서 인증 스택에 사용되는 모델이 정의됩니다. 추가 데이터베이스 모델은이 패키지에 별도의 모듈로 저장되고 __init__.py에 추가됩니다.
학생 테이블을 설정할 학생 모델을 추가하겠습니다. sqlite 데이터 베이스.
Hello\hello\model\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
모델 설정시 일부 데이터로 테이블을 초기화하려면 websetup 패키지의 bootstrap.py에 추가하십시오. 다음 문을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의 Session 개체는 ORM 개체의 모든 지속성 작업을 관리합니다.
다음 세션 방법은 CRUD 작업을 수행합니다-
DBSession.add(model object) − 매핑 된 테이블에 레코드를 삽입합니다.
DBSession.delete(model object) − 테이블에서 레코드를 삭제합니다.
DBSession.query(model).all() − 테이블에서 모든 레코드를 검색합니다 (SELECT 쿼리에 해당).
필터 속성을 사용하여 검색된 레코드 세트에 필터를 적용 할 수 있습니다. 예를 들어, student 테이블에서 city = 'Hyderabad'인 레코드를 검색하려면 다음 문을 사용하십시오.
DBSession.query(model.student).filter_by(city = ’Hyderabad’).all()
이제 컨트롤러 URL을 통해 모델과 상호 작용하는 방법을 살펴 보겠습니다.
먼저 학생의 데이터를 입력하기위한 ToscaWidgets 양식을 디자인하겠습니다.
Hello\hello\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 (Hello 응용 프로그램의 root.py)에서 다음 함수 매핑 '/ add'URL을 추가합니다.
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서버를 시작한 후 브라우저에서. 다음 학생 정보 양식이 브라우저에서 열립니다.
위의 양식은 ‘/save_record’URL. 따라서save_record() 기능을 추가해야합니다. root.py그것을 폭로합니다. 이 함수는 studentform의 데이터를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")
추가에 성공하면 브라우저가 다음으로 리디렉션됩니다. ‘/listrec’ URL. 이 URL은listrec() function. 이 함수는 student 테이블의 모든 레코드를 선택하고 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로 이동합니다. 또한 '새 레코드가 성공적으로 추가되었습니다'라는 메시지가 깜박입니다.
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>
다음과 같은 테이블 형식 데이터는 http://localhost:8080/showlist URL이 브라우저에 입력됩니다-
TurboGears는 페이지에서 출력을 나누기 위해 paginate ()라는 편리한 데코레이터를 제공합니다. 이 데코레이터는 expose () 데코레이터와 결합됩니다. @Paginate () 데코레이터는 쿼리 결과의 사전 객체를 인수로받습니다. 또한 페이지 당 레코드 수는 items_per_page 속성 값에 의해 결정됩니다. tg.decorators에서 페이지 매김 함수를 코드로 가져와야합니다.
다음과 같이 root.py에서 listrec () 함수를 다시 작성하십시오.
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)
페이지 당 항목은 3 개로 설정됩니다.
studentlist.html 템플릿에서 페이지 탐색은 py : for 지시문 아래에 tmpl_context.paginators.entries.pager ()를 추가하여 활성화됩니다. 이 템플릿의 코드는 다음과 같습니다.
<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 객체는 다음 코드로 구성됩니다.
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는 tgext.crud 및 sprox로 구동되는 tgext.admin 확장을 제공합니다. 이 Sprox는 데이터베이스 스키마에서 직접 웹 위젯을 만드는 데 사용되는 패키지입니다. 이것은 간단한 관리 페이지를 자동으로 만드는 데 사용할 수 있으며 새로 빠른 시작 응용 프로그램에서 / admin 페이지를 지원하는 도구 키트입니다.
기본적으로 관리자는 프로젝트 models / __ init__.py에서 가져온 모든 모델에 대한 자동 생성 액세스를 제공합니다.
TurboGears 관리자를 만드는 방법
기본 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)
서버를 시작한 후 다음을 방문하여 '빠른 시작'애플리케이션에 로그인하십시오. http://localhost:8080/login그런 다음 위에 표시된대로 관리자 자격 증명을 입력합니다. 브라우저는 아래와 같은 관리자 페이지를 표시합니다.
이 페이지에는이 애플리케이션에서 생성 된 모든 모델이 표시됩니다. 모델을 클릭하면 항목 목록을 볼 수 있습니다.
이 데이터 그리드 상단의 '새로 만들기'버튼을 사용하면 레코드를 추가 할 수 있습니다. 마찬가지로, 레코드 편집 및 삭제를위한 작업 버튼도이 데이터 그리드의 작업 열에 제공됩니다. 조건부로 레코드를 선택하는 검색 상자도 표시됩니다.
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 = '[email protected]'
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 = '[email protected]'
u1.password = 'editpass'
model.DBSession.add(u1)
술어 모델
tg 패키지의 술어 모듈에는 술어 검사기에 대한 정의가 포함되어 있습니다. 술어는 사용자가 요청 된 소스에 액세스 할 수 있도록 충족되어야하는 조건입니다. 이러한 술어 또는 조건은 더 많은 술어로 구성 될 수 있습니다.이를 복합 술어라고합니다. 조치 컨트롤러 또는 컨트롤러는 단일 또는 복합으로 하나의 술어 만 가질 수 있습니다.
사용자가 로그인하지 않았거나 적절한 권한이없는 경우이 술어 검사기는 repoze.who 미들웨어에 의해 포착 된 401 (HTTP Unauthorized)을 발생시켜 사용자가 로그인 할 수있는 로그인 페이지를 표시하고 완료되면 사용자가 적절한 페이지로 돌아갑니다.
tg.predicates 모듈에 정의 된 다른 조건 또는 술어는 다음과 같습니다.
Sr. 아니. | tg.predicates 모듈 및 설명 |
---|---|
1 | All 지정된 모든 술어가 충족되는지 확인하십시오. |
2 | Any 지정된 술어 중 하나 이상이 충족되는지 확인하십시오. |
삼 | is_user 인증 된 사용자의 사용자 이름이 지정된 사용자 이름인지 확인하십시오. |
4 | in_group 사용자가 특정 그룹에 속하는지 확인하십시오. |
5 | in_all_groups 사용자가 지정된 모든 그룹에 속하는지 확인하십시오. |
6 | in_any_group 사용자가 지정된 그룹 중 하나 이상에 속하는지 확인하십시오. |
7 | is_anonymous 현재 사용자가 익명인지 확인하십시오. |
8 | has_permission 현재 사용자에게 지정된 권한이 있는지 확인하십시오. |
9 | has_all_permissions 현재 사용자에게 지정된 모든 권한이 부여되었는지 확인하십시오. |
10 | has_any_permission 사용자에게 지정된 권한 중 하나 이상이 있는지 확인하십시오. |
예를 들어 술어가있는 경우 grant access user belonging to customers group, 그런 다음 다음 내장 술어 검사기를 사용할 수 있습니다-
from tg.predicates import in_group
p in_group(‘customers’)
다음 술어 검사기는 '루트'사용자 또는 '관리'권한이있는 모든 사람에게 액세스 권한을 부여합니다.
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 문서 데이터베이스도 지원합니다. Object Document Mapper API 인 Ming을 사용합니다. Ming의 사용법은 SQLAlchemy와 매우 유사합니다. Ming 쿼리 언어를 사용하면 SQLAlchemy 기반 TurboGears 프로젝트를 Ming으로 이식 할 수 있습니다.
PyMongo 란?
PyMongo는 MongoDB 작업을위한 도구가 포함 된 Python 배포입니다. Ming은 PyMongo를 확장하여-
- 선언적 모델
- 스키마 유효성 검사 및 변환
- 스키마 진화
- 순수 InMemory MongoDB 구현
- 작업 단위
- 신원지도
- 일대 다, 다 대일 및 다 대다 관계
먼저 MongoDB를 다운로드하여 설치해야합니다. MongoDB의 최신 배포는 다음에서 다운로드 할 수 있습니다.https://www.mongodb.org/downloads
Windows에서 -dbpath 옵션을 제공하여 MongoDB 서버를 시작하십시오-
C:\mongodb\bin>Mongod --dbpath d:\mongo
D:\mongo folderMongoDB 데이터베이스를 저장하도록 지정되었습니다. 서버에서 수신 시작http://localhost:27017. 이제 MongoDB 셸을 시작하려면 다음 명령을 사용하십시오.
C:\mongodb\bin>Mongo
이제 MongoDB 환경이 준비되었습니다.
이제 -ming 옵션을 사용하여 TurboGears 프로젝트를 만듭니다.
gearbox quickstart --ming Hello
이 빠른 시작 프로젝트는 SQLAlchemy 버전에 제공되는 것과 같은 인증 및 권한 부여 계층을 제공합니다. 이 응용 프로그램은 이제 로컬 컴퓨터의 포트 27017에서 서버에 연결을 시도합니다. 프로젝트 폴더의 development.ini 파일에는 다음 설정이 포함되어 있습니다.
ming.url = mongodb://localhost:27017/
ming.db = hello
다음 명령을 사용하여 프로젝트를 설정하십시오-
Python setup.py develop
프로젝트 폴더에는 다음 파일이있는 모델 하위 폴더가 있습니다.
__init__.py − 이것은 database액세스가 설정됩니다. 컬렉션은imported into this module. 예를 들어,이 패키지에 학생 컬렉션을 추가합니다.
session.py −이 파일은 session of your database connection. 선언해야 할 때마다 이것을 가져와야합니다.MappedClass 세션을 지정하려면 perform queries.
auth.py −이 파일이 생성됩니다. enabled authentication and authorization빠른 시작에서. 세 가지 컬렉션을 정의합니다.repoze.who, 사용자, 그룹 및 권한에 더 의존합니다.
컬렉션 정의
기본적으로 TurboGears는 선언적 모드에서 Ming을 구성합니다. 이는 SQLAlchemy 선언적 지원과 유사하며 MappedClass 클래스에서 상속 할 각 모델이 필요합니다.
MappedClass를 사용하려면 __mongometa__ 하위 클래스가 내부에 있어야하며, 문서를 저장하는 데 사용되는 세션과 문서를 저장하는 컬렉션의 이름에 대한 세부 정보를 추가로 제공합니다.
MappedClass에는 문서의 필드 정의도 포함됩니다. Ming의 ODM 모듈에는 다양한 유형의 필드 속성에 대한 정의가 있습니다.
- FieldProperty
- ForeignIdProperty
- RelationProperty
그만큼 ming.schema module 다음 데이터 유형을 정의합니다-
- 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
이 모델에 학생 컬렉션을 추가하려면 hello / models 폴더에 다음 코드를 student.py로 저장합니다.
안녕하세요 \ 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/)관리자 자격 증명으로 로그인하십시오. 이 애플리케이션의 관리자 페이지에는 설정된 모델 목록이 표시됩니다. (관리자로 로그인, 비밀번호 managepass)
컬렉션 생성은 MongoDB 웹 인터페이스와 MongoDB 쉘에서도 확인할 수 있습니다.
ODMSession은 다음 기능을 사용하여 여러 데이터베이스 작업을 수행하는 데 사용됩니다-
- model.query.find()
- model.query.find_and_modify()
- model.remove()
- model.update()
- model.flush()
ToscoWidget 양식 디자인
이제 ToscoWidget 양식을 디자인하여 학생 데이터를 입력하고이를 학생 모델의 기본 테이블에 추가합니다.
다음은 studentform.py를 만드는 코드입니다.
안녕하세요 \ 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')
애플리케이션의 루트 컨트롤러 '/ add'URL에서 add () 함수를 호출하면 브라우저에서 위에 설계된 양식이 열립니다. 제출 버튼은 save_record () 함수를 호출합니다. 양식 데이터를 검색하여 학생 테이블에 저장하고 애플리케이션을 학생 목록 템플릿을 노출하는 '/ listrec'URL로 리디렉션합니다.
이 활동에 대한 root.py는 다음과 같습니다.
Hello / 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 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")
다음 템플릿은 템플릿 폴더에 생성됩니다-
Hello \ templates \ 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>
Hello \ templates \ 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 브라우저에서-
데이터가 추가되고 제출 버튼을 누를 때마다 현재 항목 목록이 표시됩니다.
Gearbox 툴킷에는 TurboGears 응용 프로그램의 새 구성 요소를 빠르게 만드는 데 매우 유용한 scaffold 명령이 포함되어 있습니다. 기어 박스의 빠른 시작 명령으로 생성 된 애플리케이션에는 모델 폴더 (model.py.template), 템플릿 폴더 (template.html.template) 및 컨트롤러 폴더 (controller.py.template)에 스켈레톤 템플릿이 있습니다. 이러한 '.template'파일은 애플리케이션에 대한 새 스캐 폴드를 만들기위한 기초로 사용됩니다.
예를 들어 mymodel이라는 새 모델을 만들려면 다음 명령을 실행하면됩니다.
gearbox scaffold model mymodel
이 명령은 newmodel 클래스가 정의 된 model / mymodel.py를 생성합니다.
# -*- 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']
사용자는 이제 요구 사항에 따라 테이블 구조를 수정 한 다음 내부로 가져올 수 있습니다. model/__init__.py 애플리케이션 내에서 모델을 사용할 수 있도록합니다.
모델을 생성하려면이를 처리 할 컨트롤러 클래스와이 세 가지 구성 요소 모두를 인덱스 페이지로 다음 명령으로 동시에 생성 할 수 있습니다.
gearbox scaffold model controller template mymodel
이 명령은 MymodelController 클래스가 정식으로 정의 된 controllers \ mymodel.py를 생성합니다.
# -*- 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')
이 컨트롤러를 사용하려면 MymodelController의 인스턴스를 정의하기 위해 응용 프로그램 RootController 내에 마운트하십시오. controllers \ root.py에 다음 줄을 추가하십시오.
From hello.controller.mymodel import MymodelController
class RootController(BaseController): mymodel = MymodelController()
템플릿 스캐 폴드 templates \ mymodel.html도 templates 폴더에 생성됩니다. '/ mymodel'URL에 대한 색인 페이지 역할을합니다.
생성 mymodel.html file 템플릿 폴더에서 다음과 같습니다-
<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에는 기존 애플리케이션 내부에 동작을 연결하는 세 가지 방법이 있습니다.
Hook − 이벤트를 정의하고 이벤트가 발생하면 등록 된 리스너에게 알릴 수있는 메커니즘입니다.
Controller Wrapper− TurboGears와 Controller 사이에 위치하여 데코레이터처럼 컨트롤러를 확장 할 수 있습니다. 따라서 타사 컨트롤러 응용 프로그램에 연결할 수 있습니다.
Application Wrapper − WSGI 미들웨어와 유사하지만 TurboGears 컨텍스트에서만 작동합니다.
이 장에서는 기존 애플리케이션 내에서 후크를 사용하는 방법에 대해 설명합니다.
후크
후크는 애플리케이션의 구성 파일에 등록 된 이벤트입니다. app_cfg.py. 그런 다음 모든 컨트롤러는 이벤트 데코레이터에 의해 이러한 이벤트에 연결됩니다.
다음 후크는 TurboGears에서 정의됩니다.
Sr. 아니. | 후크 및 설명 |
---|---|
1 | Startup() 응용 프로그램 전체에만 해당되며 응용 프로그램이 시작될 때 호출됩니다. |
2 | shutdown() 애플리케이션 전체에만 해당되며 애플리케이션이 종료 될 때 호출됩니다. |
삼 | configure_new_app 응용 프로그램 구성자가 새 응용 프로그램을 생성했습니다. |
4 | before_config(app) 응용 프로그램 전체에만 해당, 응용 프로그램 생성 직후, 옵션 및 미들웨어를 설정하기 전에 호출 |
5 | after_config(app) 모든 설정을 마친 후 호출됩니다. |
6 | before_validate 유효성 검사를 수행하기 전에 호출 됨 |
7 | before_call 실제 컨트롤러 메서드를 호출하기 전에 유효성 검사 후 호출됩니다. |
8 | before_render 컨트롤러 템플릿을 렌더링하기 전에 호출되는 출력은 컨트롤러 반환 값입니다. |
9 | after_render 컨트롤러 템플릿 렌더링을 마친 후 호출됩니다. |
후크 등록
하기 위해 register a Hook, 함수 생성 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 확장은 다음으로 식별됩니다. tgext.* package. Gearbox 툴킷은 샘플 확장을 생성하는 tgext 명령을 제공합니다. 예를 들면-
gearbox tgext -n myextension
이 명령에 대한 다른 선택적 매개 변수는 다음과 같습니다.
--author − 패키지 작성자의 이름.
--email − 패키지 작성자의 이메일.
--licence− 패키지에 사용 된 라이선스. 기본값은 MIT입니다.
--description − 패키지 설명.
--keywords − 패키지 키워드 (기본값 : turbogears2.extension).
그러면 내부에 간단한 샘플 확장이있는 tgext.myextension 디렉토리가 생성됩니다.
Run the setup.py 디렉토리 내부-
Python setup.py install
그만큼 _init_.py 내부 파일 tgext/myextension 폴더 포함-
Plugme function − 이것은 확장의 진입 점입니다.
SetupExtension class − 여기서 확장 초기화가 발생합니다.
On_startup function − 클래스 내부에는 클래스 내부의 __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
확장 프로그램에서 모델과 컨트롤러를 노출해야하는 경우 Pluggable Applications, 이는 기능을 확장하기 위해 다른 응용 프로그램에 연결할 수있는 재사용 가능한 Turbogears 응용 프로그램을 생성하기위한 것입니다.
다음 기어 박스 명령을 사용하여 플러그 형 애플리케이션을 만듭니다.
gearbox quickstart-pluggable plugtest
이러한 플러그 형 응용 프로그램은 자신을 정의 할 수 있습니다.
Controllers − 애플리케이션이 제거 될 때 자동으로 마운트됩니다.
Models − 연결된 애플리케이션 내부 및 외부에서 사용할 수 있습니다.
Helpers − 애플리케이션 템플릿의 'H'개체에 자동으로 노출 될 수 있습니다.
Bootstrap − setup-app이 호출 될 때 실행됩니다.
Statics -자체 개인 경로에서 사용할 수 있습니다.
이 plugtest 응용 프로그램을 설치하고 다음과 같이 수정하여 동일하게 마운트하십시오. app_cfg.py.
from tgext.pluggable import plug
plug(base_config, plugtest)
REST는 RE프리젠 테이션 S테이트 Transfer. REST는 웹 표준 기반 아키텍처이며 데이터 통신에 HTTP 프로토콜을 사용합니다. 모든 구성 요소가 리소스이고 HTTP 표준 메서드를 사용하여 공통 인터페이스에서 리소스에 액세스하는 리소스를 중심으로 회전합니다. REST는Roy Fielding in 2000.
RestController 란?
TurboGears의 RestController는 URL뿐만 아니라 요청의 메서드에 액세스하는 메커니즘을 제공합니다. 표준 HTTP 설명에는 GET, POST, PUT 및 DELETE가 포함됩니다. RestController는 이러한 기능을 지원하며, 사용자가 데이터를 양식 및 목록으로 표시 할 수 있도록 URL 디스패치에 대한 몇 가지 바로 가기를 추가합니다.
RESTful이 TurboGears와 작동하는 방식을 설명하기 위해 학생 목록을 노출하는 간단한 웹 서비스를 정의 할 것입니다.
학생 모델의 코드는 다음과 같습니다.
model \ 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 형식으로 학생 목록을 나열하는보기 기능을 제공합니다.
Controllers \ 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)
다음 줄을 통합하여 응용 프로그램의 RootController에이 StudentController를 마운트합니다. root.py −
from hello.controllers.student import StudentController
class RootController(BaseController):
students = StudentController()
가는 http://localhost:8080/students json 형식으로 인코딩 된 학생들의 목록을 제공합니다.
post 메소드를 사용하여 학생을 데이터베이스에 저장하는 방법을 정의합니다. 이 메서드는 http://localhost:8080/student URL은 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 웹 애플리케이션을 배포하는 데 사용할 수있는 다양한 옵션이 있습니다.
mod_wsgi를 사용하는 Apache
mod_wsgi는 Graham Dumpleton이 개발 한 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
Circus는 프로세스 및 소켓 관리자입니다. 프로세스와 소켓을 모니터링하고 제어하는 데 사용할 수 있습니다. Chaussette WSGI 서버와 함께 사용하면 애플리케이션을 배포하고 애플리케이션에 필요한 모든 관련 프로세스를 관리 할 수있는 강력한 도구가 될 수 있습니다.
TurboGears-GoogleAppEngine
다음 URL에서 Python 용 Google AppEngine SDK를 설치합니다. https://cloud.google.coms
시스템에 Google AppEngine을 설치합니다. 그런 다음 Google 개발자 콘솔을 열고 Google 계정으로 로그인하십시오.https://console.developers.google.com/start
라는 새 프로젝트를 만듭니다. mytgapp −
Google AppEngine Launcher를 사용하여 mytgapp.
다음 파일은 지정된 디렉토리에 생성됩니다-
- 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에서 애플리케이션을 실행하고 찾아보기 버튼을 클릭하여 애플리케이션이 localhost에서 제대로 작동하는지 확인합니다.
우리는 이미 개발자 콘솔에 mytgapp이라는 프로젝트를 만들었습니다. 이제 Launcher에서 배포 버튼을 클릭하십시오. 배포 프로세스가 끝나면http://mytgapp.appspot.com/ 온라인으로 신청서를 보려면 방문하십시오.