Turbogears - Hướng dẫn nhanh
Web Framework là gì?
Web Application Framework hay đơn giản là Web Framework đại diện cho một tập hợp các thư viện và mô-đun, cho phép nhà phát triển ứng dụng web viết các ứng dụng mà không cần phải bận tâm về các chi tiết cấp thấp như giao thức, quản lý luồng, v.v.
TurboGears là gì?
TurboGears là một khung ứng dụng web được viết bằng Python. Ban đầu được tạo ra bởi Kevin Dangoor vào năm 2005, phiên bản mới nhất TurboGears (ver 2.3.7) được quản lý bởi một nhóm các nhà phát triển do Mark Ramm và Florent Aide dẫn đầu.
TurboGears tuân theo mô hình Model-View-Controller cũng như hầu hết các khung công tác web hiện đại như Rails, Django, Struts, v.v.
Bộ điều khiển xem mô hình
MVC là một mẫu thiết kế phần mềm để phát triển các ứng dụng web. Mẫu Bộ điều khiển Chế độ xem Mô hình được tạo thành từ ba phần:
Model - Mức thấp nhất của mẫu có trách nhiệm duy trì dữ liệu.
View - Điều này có trách nhiệm hiển thị tất cả hoặc một phần dữ liệu cho người dùng.
Controller - Mã phần mềm kiểm soát các tương tác giữa Mô hình và Chế độ xem.
MVC phổ biến vì nó tách biệt logic ứng dụng khỏi lớp giao diện người dùng và hỗ trợ tách các mối quan tâm. Tại đây, Bộ điều khiển nhận tất cả các yêu cầu cho ứng dụng và sau đó làm việc với Mô hình để chuẩn bị bất kỳ dữ liệu nào mà Chế độ xem cần. Sau đó, Chế độ xem sử dụng dữ liệu do Bộ điều khiển chuẩn bị để tạo ra phản hồi có thể trình bày cuối cùng. Phần trừu tượng MVC có thể được biểu diễn bằng đồ thị như sau:
Ngươi mâu
Model chịu trách nhiệm quản lý dữ liệu của ứng dụng. Nó phản hồi yêu cầu từ khung nhìn và nó cũng phản hồi các hướng dẫn từ bộ điều khiển để tự cập nhật.
Xem
Bản trình bày dữ liệu theo một định dạng cụ thể, được kích hoạt bởi quyết định trình bày dữ liệu của người kiểm soát. Chúng là hệ thống tạo khuôn mẫu dựa trên kịch bản rất dễ tích hợp với công nghệ AJAX.
Bộ điều khiển
Bộ điều khiển chịu trách nhiệm phản hồi đầu vào của người dùng và thực hiện các tương tác trên các đối tượng mô hình dữ liệu. Bộ điều khiển nhận đầu vào, nó xác nhận đầu vào và sau đó thực hiện hoạt động nghiệp vụ sửa đổi trạng thái của mô hình dữ liệu.
TurboGears được xây dựng dựa trên một số thư viện và công cụ. Các công cụ này đã thay đổi giữa các phiên bản TurboGears khác nhau. Các thành phần của phiên bản hiện tại (phiên bản 2.3.7) được liệt kê bên dưới.
SQLAlchemy
Nó là một bộ SQL mã nguồn mở cung cấp ánh xạ quan hệ đối tượng (ORM) cho mã Python.
Genshi
Công cụ tạo khuôn mẫu này được sử dụng để xây dựng front-end của các ứng dụng TG. Hệ thống tạo khuôn mẫu web kết hợp một mẫu với một nguồn dữ liệu nhất định để hiển thị các trang web động.
ToscaWidgets
Nó là một thư viện widget để tạo các biểu mẫu HTML với các điều khiển phía máy chủ. Tosca cũng hoạt động như một phần mềm trung gian để kết nối với các widget và bộ công cụ JavaScript.
Hộp số
Nó cung cấp một tập hợp các lệnh để quản lý các dự án và ứng dụng TurboGears máy chủ. Các ứng dụng TurboGears có thể được triển khai trên bất kỳ máy chủ web nào tương thích với WSGI.
Giao diện Cổng vào Máy chủ Web (WSGI) đã được chấp nhận làm tiêu chuẩn để phát triển ứng dụng web Python. WSGI là một đặc điểm kỹ thuật cho giao diện chung giữa máy chủ web và các ứng dụng web. Gói wsgiref là một triển khai tham chiếu của WSGI. Nó được sử dụng để thêm hỗ trợ WSGI vào khung web TurboGears web. Mô-đun simple_server trong gói này triển khai một máy chủ HTTP đơn giản phục vụ các ứng dụng WSGI. Chúng tôi sẽ sử dụng nó để kiểm tra các ứng dụng được phát triển trong hướng dẫn này.
Điều kiện tiên quyết
Python 2.6 trở lên. Các phiên bản trước đó của TurboGears không tuân thủ Python 3.X. Phiên bản mới nhất tuyên bố hoạt động tốt trên Python 3.X. Tuy nhiên, tài liệu chính thức của TurboGears vẫn dựa trên môi trường Python 2.7.
Lệnh sau installs virtualenv -
pip install virtualenv
Lệnh này cần administratorcác đặc quyền. Thêm vàosudo before piptrên Linux / Mac OS. Nếu bạn đang sử dụng Windows, hãy đăng nhập với tư cách Quản trị viên. Trên Ubuntu virtualenv có thể được cài đặt bằng trình quản lý gói của nó.
Sudo apt-get install virtualenv
Sau khi cài đặt, môi trường ảo mới được tạo trong một thư mục.
mkdir newproj
cd newproj
virtualenv venv
Để kích hoạt môi trường tương ứng, trên Linux/OS X
venv/bin/activate
trên Windows
venv\scripts\activate
Bây giờ chúng tôi đã sẵn sàng install TurboGearstrong môi trường này. Việc cài đặt TurboGears tối thiểu được thực hiện bằng lệnh sau:
pip install TurboGears2
Lệnh trên có thể được chạy trực tiếp mà không cần môi trường ảo để cài đặt trên toàn hệ thống.
Để cài đặt TurboGears cùng với các công cụ phát triển, hãy sử dụng lệnh sau:
pip install tg.devtools
TurboGears có một chế độ tối thiểu giúp bạn có thể tạo các ứng dụng tệp đơn một cách nhanh chóng. Các ví dụ và dịch vụ đơn giản có thể được xây dựng nhanh chóng với tập hợp phụ thuộc tối thiểu.
Lớp ứng dụng trong ứng dụng TG được kế thừa từ TGControllerlớp học. Các phương thức trong lớp này có sẵn để truy cập bởi@expose trang trí từ tgmô-đun. Trong ứng dụng đầu tiên của chúng tôi,index()phương thức được ánh xạ dưới dạng thư mục gốc của ứng dụng của chúng tôi. Lớp TGController cũng cần được nhập từtg mô-đun.
from tg import expose, TGController
class MyController(TGController):
@expose()
def index(self):
return 'Hello World turbogears'
Tiếp theo, thiết lập cấu hình của ứng dụng và khai báo đối tượng ứng dụng. AppConfig phương thức khởi tạo lớp ở đây nhận hai tham số - thuộc tính tối thiểu được đặt thành true và lớp điều khiển.
config = AppConfig(minimal = True, root_controller = RootController())
application = config.make_wsgi_app()
Các make_wsgi_app() ở đây hàm tạo đối tượng ứng dụng.
Để phục vụ ứng dụng này, bây giờ chúng ta cần khởi động máy chủ HTTP. Như đã đề cập trước đó, chúng ta sẽ sử dụngsimple_server mô-đun trong wsgirefgói để thiết lập và khởi động nó. Mô-đun này cómake_server() phương thức yêu cầu số cổng và đối tượng ứng dụng làm đối số.
from wsgiref.simple_server import make_server
server = make_server('', 8080, application)
server.serve_forever()
Có nghĩa là ứng dụng của chúng tôi sẽ được phân phát tại cổng số 8080 của localhost.
Sau đây là mã hoàn chỉnh của ứng dụng TurboGears đầu tiên của chúng tôi -
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()
Chạy tập lệnh trên từ trình bao Python.
Python app.py
Đi vào http://localhost:8080 trong thanh địa chỉ của trình duyệt để xem thông báo 'Hello World TurboGears'.
Các tg.devtoolscủa TurboGears chứa Hộp số. Nó là một tập hợp các lệnh, rất hữu ích để quản lý các dự án TG phức tạp hơn. Các dự án ngăn xếp đầy đủ có thể được tạo nhanh chóng bằng lệnh Hộp số sau:
gearbox quickstart HelloWorld
Điều này sẽ tạo ra một dự án có tên HelloWorld.
Một dự án TurboGears chứa các thư mục sau:
Config - Nơi thiết lập và cấu hình dự án dựa vào
Controllers - Tất cả các bộ điều khiển dự án, logic của ứng dụng web
i018n - Các tệp dịch cho các ngôn ngữ được hỗ trợ
Lib - Các chức năng và lớp python tiện ích
Model - Mô hình cơ sở dữ liệu
Public Static Files - CSS, JavaScript và hình ảnh
Templates - Các mẫu do bộ điều khiển của chúng tôi hiển thị.
Tests - Bộ bài kiểm tra đã thực hiện.
Websetup - Các chức năng thực thi lúc thiết lập ứng dụng.
Cách cài đặt một dự án
Dự án này bây giờ cần được cài đặt. Asetup.pyđã được cung cấp trong thư mục cơ sở của dự án. Các phần phụ thuộc của dự án được cài đặt khi tập lệnh này được thực thi.
Python setup.py develop
Theo mặc định, các phần phụ thuộc sau được cài đặt tại thời điểm thiết lập dự án:
- Beaker
- Genshi
- zope.sqlalchemy
- sqlalchemy
- alembic
- repoze.who
- tw2.forms
- tgext.admin ≥ 0.6.1
- WebHelpers2
- babel
Sau khi cài đặt, hãy bắt đầu phục vụ dự án trên máy chủ phát triển bằng cách đưa ra lệnh sau trong shell:
Gearbox serve –reload –debug
Làm theo lệnh đã đề cập ở trên để phục vụ một dự án mẫu được tạo trước. Mởhttp://localhost:8080trong trình duyệt. Ứng dụng mẫu làm sẵn này giới thiệu ngắn gọn về bản thân khung công tác TurboGears.
Trong dự án Xin chào này, bộ điều khiển mặc định được tạo trong thư mục bộ điều khiển như Hello/hello/controllers.root.py. Hãy để chúng tôimodify root.py với mã sau -
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"
Khi một ứng dụng làm việc cơ bản đã sẵn sàng, có thể thêm nhiều dạng xem hơn trong lớp bộ điều khiển. bên trongMycontroller lớp trên, một phương thức mới sayHello()được thêm vào. Các@expose() người trang trí đính kèm /sayHelloURL của nó. Hàm này được thiết kế để chấp nhận tên dưới dạng tham số từ URL.
Sau khi khởi động máy chủ thông qua lệnh 'phục vụ hộp số', http://localhost:8080. Thông báo Hello World sẽ được hiển thị trong trình duyệt, ngay cả khi các URL sau được nhập:
http://localhost:8080/
http://localhost:8080/index
Tất cả các URL này được ánh xạ tới RootController.index()phương pháp. Lớp này cũng có_default()phương thức sẽ được gọi, bất cứ khi nào một URL không được ánh xạ tới bất kỳ hàm cụ thể nào. Phản hồi với URL được ánh xạ tới một hàm bởi @expose () decorator.
Có thể gửi một tham số đến một hàm được hiển thị từ URL. Hàm sau đọc tham số tên từ URL.
@expose()
def sayHello(self, name):
return '<h3>Hello %s</h3>' %name
Kết quả sau sẽ được hiển thị trong trình duyệt dưới dạng phản hồi cho URL: http://localhost:8080/?name=MVL
Hello MVL
TurboGears tự động ánh xạ các tham số URL thành các đối số của hàm. Lớp RootController của chúng tôi được kế thừa từ BaseController. Điều này được định nghĩa làbase.py bên trong lib folder ứng dụng.
Mã của nó như sau:
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__ gửi đến phương thức Controller mà yêu cầu được chuyển đến.
Một Sự kiện mặc dù nội dung HTML có thể được trả lại cho trình duyệt, để có đầu ra nâng cao hơn, việc sử dụng công cụ mẫu luôn được ưu tiên. Trong một dự án ngăn xếp đầy đủ được 'khởi động nhanh' bằng hộp số, Genshi được bật làm trình kết xuất mẫu mặc định. Tuy nhiên, trong một ứng dụng tối thiểu, Genshi (hoặc bất kỳ công cụ mẫu nào khác, chẳng hạn như jinja) cần được cài đặt và kích hoạt. Công cụ mẫu Genshi cho phép viết các mẫu trong xhtml thuần túy và xác nhận chúng để phát hiện các vấn đề tại thời điểm biên dịch và ngăn chặn việc cung cấp các trang bị hỏng.
Các mẫu được tham chiếu bằng cách sử dụng ký hiệu chấm. Trong dự án Hello của chúng tôi, một thư mục mẫu được cung cấp để lưu trữ các trang web mẫu. Vì thếsample.html sẽ được gọi là hello.templates.sample(phần mở rộng không được đề cập). TurboGears kết xuất mẫu này thông qua trình trang trí hiển thị để liên kết phương pháp bộ điều khiển với nó bằng cáchtg.render_template() chức năng.
Hàm bộ điều khiển được tiếp xúc trả về một đối tượng từ điển Python. Đối tượng từ điển này đến lượt nó được chuyển cho mẫu được liên kết. Phần giữ chỗ trong mẫu chứa đầy các giá trị từ điển.
Để bắt đầu, hãy để chúng tôi hiển thị một trang web với tập lệnh html thuần túy. Bộ điều khiển tiếp xúc trả về mộtnull dictionary object vì chúng tôi không có ý định gửi bất kỳ dữ liệu nào được phân tích cú pháp bên trong tập lệnh HTML.
Cách tạo HTML mẫu
Của chúng tôi sample.htmlđược đưa ra dưới đây. Đảm bảo rằng nó được lưu trữ trong thư mục mẫu của dự án.
<html>
<head>
<title>TurboGears Templating Example</title>
</head>
<body>
<h2>Hello, Welcome to TurboGears!.</h2>
</body>
</html>
Thêm vào sample() chức năng trong root.py và hiển thị sample.html thông qua nó.
@expose("hello.templates.sample")
def sample(self):
return {}
Kết quả sau sẽ được hiển thị trong trình duyệt khi một URL http://localhost:8080/sample được nhập sau khi khởi động máy chủ web.
Như đã đề cập ở trên, một đối tượng từ điển được gửi dưới dạng tập hợp các tham số đến một khuôn mẫu Genshi. Mẫu này chứa 'các trình giữ chỗ', được điền động với các thông số nhận được từ bộ điều khiển.
Hãy để chúng tôi thay đổi sample() chức năng gửi một đối tượng từ điển đến mẫu mẫu.
@expose("hello.templates.sample")
def sample(self,name):
mydata = {'person':name}
return mydata
Tạo nên sample.html trong thư mục mẫu (templates\sample.html)
<html>
<head>
<title>TurboGears Templating Example</title>
</head>
<body>
<h2>Hello, my name is ${person}!.</h2>
</body>
</html>
Trong mã HTML ở trên, ${person}là trình giữ chỗ. Đi vàohttp://localhost:8080/sample?name=MVLdưới dạng URL trong trình duyệt. URL này được ánh xạ tớisample()trong bộ điều khiển gốc của chúng tôi. Nó trả về một đối tượng từ điển. Điều này được chọn bởi trang mẫu liên kết sample.html trong thư mục mẫu. $ {Person} sau đó được MVL thay thế trong trang web.
Cũng có thể truy cập dữ liệu biểu mẫu HTML trong một hàm bộ điều khiển. Biểu mẫu HTML sử dụng để gửi dữ liệu biểu mẫu.
Giao thức Http là nền tảng của giao tiếp dữ liệu trong world wide web. Các phương pháp truy xuất dữ liệu khác nhau từ URL đã chỉ định được xác định trong giao thức này. Bảng sau đây tóm tắt các phương thức http khác nhau:
Sr.No. | Phương thức và mô tả HTTP |
---|---|
1 | GET Gửi dữ liệu ở dạng không được mã hóa đến máy chủ. Phương pháp phổ biến nhất. |
2 | HEAD Giống như GET, nhưng không có nội dung phản hồi |
3 | POST Được sử dụng để gửi dữ liệu biểu mẫu HTML đến máy chủ. Dữ liệu nhận được bằng phương thức POST không được máy chủ lưu vào bộ nhớ đệm. |
4 | PUT Thay thế tất cả các bản trình bày hiện tại của tài nguyên đích bằng nội dung đã tải lên. |
5 | DELETE Loại bỏ tất cả các đại diện hiện tại của tài nguyên mục tiêu được cung cấp bởi một URL |
Tạo một biểu mẫu HTML
Hãy để chúng tôi tạo một Biểu mẫu HTML và gửi dữ liệu biểu mẫu đến một URL. Lưu tập lệnh sau dưới dạng 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>
Dữ liệu đã nhập trong biểu mẫu này sẽ được gửi đến ‘/login’ URL. Bây giờ hãy tạo một hàm điều khiểnloginpage() và hiển thị trang html ở trên với nó.
@expose("hello.templates.login")
def loginpage(self):
return {}
Để nhận dữ liệu biểu mẫu, hãy cung cấp login()bộ điều khiển, có các thuộc tính biểu mẫu làm tham số của nó. Đây‘nm’ là tên của trường nhập văn bản trong biểu mẫu đăng nhập, giống được sử dụng làm tham số của hàm login ().
@expose("hello.templates.sample")
def login(self, nm):
name = nm
return {'person':name}
Như có thể thấy, dữ liệu nhận được từ biểu mẫu đăng nhập đang được gửi đến mẫu sample.html (được sử dụng trước đó). Nó được phân tích cú pháp bởi mộtGenshi template engine để tạo ra kết quả sau:
Phương pháp ĐĂNG
Khi biểu mẫu HTML sử dụng phương thức POST để gửi dữ liệu đến thuộc tính URL trong hành động, dữ liệu biểu mẫu không được hiển thị trong URL. Dữ liệu mã hóa được nhận trong mộtdictđối số của hàm điều khiển. Các **kw đối số bên dưới là đối tượng từ điển giữ dữ liệu.
Biểu mẫu HTML chứa hai trường văn bản đầu vào.
<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>
Các marks() bộ điều khiển nhận dữ liệu biểu mẫu và gửi nó đến sample.htmlbản mẫu. Mã choroot.py như sau -
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
Cuối cùng, mẫu sample.html như sau:
<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>
Khởi động máy chủ (nếu chưa chạy)
Gearbox server –reload –debug
Đi vào http://localhost::8080/marksform trong trình duyệt
Các sample.html sẽ hiển thị đầu ra sau -
Genshi là một ngôn ngữ khuôn mẫu dựa trên XML. Nó tương tự nhưKid, từng là công cụ mẫu cho các phiên bản trước đó của TurboGears. Genshi cũng như Kid được lấy cảm hứng từ các ngôn ngữ mẫu nổi tiếng khác nhưHSLT, TAL và PHP.
Mẫu Genshi bao gồm các chỉ thị xử lý. Các Chỉ thị này là các phần tử và thuộc tính trong một mẫu. Các chỉ thị Genshi được xác định trong một không gian tênhttp://genshi.edgewall.org/. Do đó không gian tên này cần được khai báo trong phần tử gốc của mẫu.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:py = "http://genshi.edgewall.org/"
lang = "en">
...
</html>
Khai báo trên có nghĩa là không gian tên mặc định được đặt thành XHTML và các chỉ thị Genshi có tiền tố 'py'.
Genshi Directives
Một số chỉ thị được định nghĩa trong Genshi. Danh sách sau liệt kê các chỉ thị Genshi -
- py:if
- py:choose
- py:for
- py:def
- py:match
- py:with
- py:replace
- py:content
- py:attrs
- py:strip
Phần có điều kiện
Genshi cung cấp hai chỉ thị để hiển thị có điều kiện nội dung - py: if và py: select.
py: nếu
Nội dung của phần tử của chỉ thị này sẽ chỉ được hiển thị nếu biểu thức trong if clauseđánh giá đúng. Giả sử rằng dữ liệu trong ngữ cảnh mẫu là{‘foo’:True, ‘bar’:’Hello’}, chỉ thị sau -
<div>
<b py:if = "foo">${bar}</b>
</div>
sẽ cho kết quả
Hello
Tuy nhiên, đầu ra này sẽ không được hiển thị nếu ‘foo’ is set to False.
Chỉ thị này cũng có thể được sử dụng như một phần tử. Trong trường hợp này<py:if> phải được đóng bởi tương ứng </py:if>
<div>
<py:if test = "foo">
<b>${bar}</b>
</py:if>
</div>
py: chọn
Có thể xử lý có điều kiện nâng cao với việc sử dụng py:choose kết hợp với py:when và py:otherwisecác chỉ thị. Tính năng này tương tự nhưswitch – case xây dựng trong C/C++.
Biểu hiện trong py:choose chỉ thị được kiểm tra với các giá trị khác nhau được xác định với py:whencác lựa chọn thay thế và nội dung tương ứng sẽ được hiển thị. Một giải pháp thay thế mặc định có thể được cung cấp dưới dạngpy:otherwise chỉ thị.
<div py:choose = "foo”>
<span py:when = "0">0</span>
<span py:when = "1">1</span>
<span py:otherwise = "">2</span>
</div>
Ví dụ sau minh họa việc sử dụng py:choose và py:whencác chỉ thị. Biểu mẫu HTML đăng dữ liệu lên / đánh dấu URL. Cácmarks() hàm chuyển hướng các dấu và kết quả dưới dạng một đối tượng từ điển đến total.htmlbản mẫu. Hiển thị có điều kiện củaresult Pass/Fail đạt được bằng cách sử dụng py:choose và py:when các chỉ thị.
Tập lệnh HTML nhập dấu (marks.html) như sau -
<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>
Mã hoàn chỉnh của root.pylà như sau. Cácmarks() bộ điều khiển đang gửi điểm và kết quả tới total.html mẫu -
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
Các total.html trong thư mục mẫu nhận dữ liệu từ điển và phân tích cú pháp nó trong đầu ra html có điều kiện như sau:
<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>
Khởi động máy chủ (nếu chưa chạy)
Gearbox server –reload –debug
Đi vào http://localhost::8080/marksform trong trình duyệt -
Các total.html sẽ hiển thị đầu ra sau -
py: cho
Phần tử trong chỉ thị py: for được lặp lại cho từng mục trong một đối tượng có thể lặp lại, thường là đối tượng Danh sách Python. Nếuitems = [1,2,3] có trong ngữ cảnh mẫu, nó có thể được lặp lại bằng cách sau py: for chỉ thị -
<ul>
<li py:for = "item in items">${item}</li>
</ul>
Kết quả sau sẽ được hiển thị:
1
2
3
Ví dụ sau cho thấy dữ liệu biểu mẫu HTML được hiển thị trong mẫu total.html sử dụng py: for chỉ thị cũng có thể được sử dụng như sau:
<py:for each = "item in items">
<li>${item}</li>
</py:for>
Tập lệnh biểu mẫu 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>
Các loop() controller đọc dữ liệu biểu mẫu và gửi nó đến total.template dưới dạng một đối tượng danh sách.
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})
Mẫu temp.html sử dụng vòng lặp py: for để hiển thị nội dung của đối tượng dict dưới dạng một bảng.
<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>
Khởi động máy chủ (nếu chưa chạy)
gearbox server –reload –debug
Đi vào http://localhost::8080/marksform trong trình duyệt.
Kết quả sau sẽ được hiển thị trong trình duyệt khi biểu mẫu trên được gửi.
py: def
Chỉ thị này được sử dụng để tạo macro. Macro là một đoạn mã mẫu có thể sử dụng lại. Giống như một hàm Python, nó có một tên và có thể có các tham số tùy chọn. Đầu ra của macro này có thể được chèn vào bất kỳ vị trí nào trong mẫu.
Lệnh py: def tuân theo cú pháp sau:
<p py:def = "greeting(name)">
Hello, ${name}!
</p>
Macro này có thể được hiển thị với một giá trị biến thành tham số 'name'.
${greeting('world')} ${greeting('everybody)}
Chỉ thị này cũng có thể được sử dụng với một phiên bản cú pháp khác như sau:
<py:def function = "greeting(name)">
<p>Hello, ${name}! </p>
</py:def>
Trong ví dụ sau, macro() điều khiển trong root.py gửi một dict đối tượng có hai khóa name1 và name2 vào mẫu 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'}
Mẫu macro.html này chứa định nghĩa về macro được gọi là lời chào. Nó được sử dụng để tạo thông báo chào mừng cho dữ liệu nhận được từ bộ điều khiển.
<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>
Khởi động máy chủ bằng hộp số
gearbox serve –reload –debug
Gọi bộ điều khiển macro () bằng cách nhập URL sau vào trình duyệt -
http://localhost:8080/macro
Kết quả sau sẽ được hiển thị trong trình duyệt -
py: với
Chỉ thị này cho phép bạn gán các biểu thức cho các biến cục bộ. Các biến cục bộ này làm cho biểu thức bên trong ít dài dòng hơn và hiệu quả hơn.
Giả sử rằng x = 50 được cung cấp trong dữ liệu ngữ cảnh cho một mẫu, sau đây sẽ là lệnh py: with -
<div>
<span py:with = "y = 50; z = x+y">$x $y $z</span>
</div>
Nó sẽ dẫn đến kết quả sau:
50 50 100
Một phiên bản thay thế cho py: với chỉ thị cũng có sẵn -
<div>
<py:with = "y = 50; z = x+y">$x $y $z</py:with>
</div>
Trong ví dụ sau, bộ điều khiển macro () trả về một đối tượng dict với các khóa tên, phy và toán học.
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}
Mẫu macro.html thêm các giá trị của các khóa phy và toán học bằng cách sử dụng lệnh 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>
Trình duyệt sẽ hiển thị đầu ra sau để phản hồi lại URL http://localhost:8080/macro
Chỉ thị thao tác cấu trúc
Các py:attrs chỉ thị thêm, sửa đổi hoặc loại bỏ các thuộc tính khỏi phần tử.
<ul>
<li py:attrs = "foo">Bar</li>
</ul>
Nếu foo = {‘class’:’collapse’} có trong ngữ cảnh mẫu, đoạn mã trên sẽ hiển thị.
<ul>
<li class = "collapse">Bar</li>
</ul>
Các py:content chỉ thị thay thế mọi nội dung lồng nhau bằng kết quả đánh giá biểu thức -
<ul>
<li py:content = "bar">Hello</li>
</ul>
Cho bar = 'Bye' trong dữ liệu ngữ cảnh, điều này sẽ tạo ra
<ul>
<li>Bye</li>
</ul>
Các py:replace chỉ thị thay thế chính phần tử bằng kết quả đánh giá biểu thức -
<div>
<span py:replace = "bar">Hello</span>
</div>
Cho bar = 'Bye' trong dữ liệu ngữ cảnh, nó sẽ tạo ra
<div>
Bye
</div>
Nội dung của một tài liệu XML khác (đặc biệt là tài liệu HTML) có thể được đưa vào bằng cách sử dụng các thẻ bao gồm trong tài liệu hiện tại. Để kích hoạt tính năng này, không gian tên XInclude phải được khai báo trong phần tử gốc của tài liệu HTML.
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:xi = "http://www.w3.org/2001/XInclude >
Khai báo trên chỉ định rằng chỉ thị bao gồm chứa ‘xi’tiếp đầu ngữ. Để thêm nội dung của một trang html khác trong tài liệu hiện tại, hãy sử dụng lệnh xi: include như sau:
<xi:include href = "somepage.html" />
Trong ví dụ sau, root.py chứa bộ điều khiển include (), cho thấy bao gồm.html.
from hello.lib.base import BaseController
from tg import expose, request
class RootController(BaseController):
@expose('hello.templates.include')
def include(self):
return {}
HTML đầu trang và chân trang
Trong include.html, không gian tên include được khai báo và nội dung của header.html và footer.html được thêm vào. Đây là tập lệnh HTML của template \ 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>
Đây là mã mẫu \ header.html -
<html>
<head>
<title>TurboGears Templating Example</title>
</head>
<body>
<h1>This is page Header</h1>
</body>
</html>
Sau đây là các mẫu \ footer.html
<html>
<head>
<title>TurboGears Templating Example</title>
</head>
<body>
<h3>This is page footer</h3>
</body>
</html>
Bắt đầu phát triển bằng hộp số và nhập http://localhost:8080/includetrong trình duyệt. Kết quả hiển thị sẽ như hình dưới đây -
Bằng cách này có thể đạt được cấu trúc mô-đun của các khung nhìn. Nếu tài nguyên được đề cập trong chỉ thị xi: include không có sẵn, một lỗi sẽ xuất hiện. Trong trường hợp này, một tài nguyên thay thế có thể được tải bằng cách sử dụng xi: dự phòng.
<xi:include href = “main.html”>
<xi:fallback href = ”default.html”/>
</xi.include>
Việc bao gồm nội dung có thể được tạo động dưới dạng thuộc tính href có thể chứa các biểu thức.
Thêm bộ điều khiển sau trong root.py.
@expose('hello.templates.ref-include')
def refinclude(self):
return {'pages':['heading','main','footer']}
Lưu mã sau dưới dạng ref-include.html trong thư mục mẫu.
<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>
Trước khi khởi động máy chủ, hãy đảm bảo rằng thư mục mẫu có header.html, main.html và footer.html. Đi vàohttp://localhost:8082/refinclude trong trình duyệt để nhận kết quả sau
Các @expose()decorator theo mặc định hiển thị nội dung html. Tuy nhiên, điều này có thể được đặt thànhjson content type. TurboGears hỗ trợ kết xuất json thông quatg.jsonify.JSONEncoder (**kwargs)lớp học. Để hiển thị dữ liệu json, chỉ cần chuyển json làm loại nội dung để hiển thị trình trang trí.
@expose('json')
def jsondata(self, **kwargs):
return dict(hello = 'World')
Nếu URL '/ jsondata' được nhập vào trình duyệt, nó sẽ phản hồi bằng cách hiển thị -
{"hello": "World"}
jsonp Rendering
jsonp là viết tắt của json với padding. Nó hoạt động tương tự như đầu ra json ngoại trừ thực tế là nó cung cấp phản hồi ứng dụng / javascript với lời gọi hàm javascript cung cấp tất cả các giá trị được bộ điều khiển trả về dưới dạng đối số hàm.
Để kích hoạt hiển thị jsonp, trước tiên bạn phải thêm nó vào danh sách các công cụ cần thiết bên trong ứng dụng của bạn - config/app_cfg.py -
base_config.renderers.append('jsonp')
Viết trang trí tiếp xúc của bạn như sau:
@expose('json')
@expose('jsonp')
def jsonpdata (self, **kwargs):
return dict(hello = 'World')
Khi truy cập / jsonpdata? Callback = callme, bạn sẽ thấy:
callme({"hello": "World"});
Đôi khi, một ứng dụng web có thể yêu cầu cấu trúc URL có nhiều hơn một cấp. TurboGears có thể duyệt qua hệ thống phân cấp đối tượng để tìm ra phương pháp thích hợp có thể xử lý yêu cầu của bạn.
Một dự án 'bắt đầu nhanh' với hộp số có lớp BaseController trong thư mục lib của dự án. Nó có sẵn dưới dạng 'Hello / hello / lib / base.py'. Nó đóng vai trò là lớp cơ sở cho tất cả các bộ điều khiển phụ. Để thêm cấp độ phụ của URL trong ứng dụng, hãy thiết kế một lớp phụ có tên là BlogController bắt nguồn từ BaseController.
BlogController này có hai hàm điều khiển, index () và post (). Cả hai đều được thiết kế để hiển thị mỗi mẫu, blog.html và post.html.
Note - Các mẫu này được đặt bên trong một thư mục con - template / 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}
Bây giờ khai báo một đối tượng của lớp này trong lớp RootController (trong root.py) như sau:
class RootController(BaseController):
blog = BlogController()
Các chức năng điều khiển khác cho URL cấp cao nhất sẽ có trong lớp này như trước đó.
Khi một URL http://localhost:8080/blog/được nhập, nó sẽ được ánh xạ tới hàm điều khiển index () bên trong lớp BlogController. Tương tự,http://localhost:8080/blog/post sẽ gọi hàm post ().
Mã cho blog.html và post.html như sau:
Blog.html
<html>
<body>
<h2>My Blog</h2>
</body>
</html>
post.html
<html>
<body>
<h2>My new post dated $date</h2>
</body>
</html>
Khi một URL http://localhost:8080/blog/ được nhập, nó sẽ tạo ra kết quả sau:
Khi một URL http://localhost:8080/blog/post được nhập, nó sẽ tạo ra kết quả sau:
Một trong những khía cạnh quan trọng nhất của bất kỳ ứng dụng web nào là trình bày giao diện người dùng cho người dùng. HTML cung cấp thẻ <form> được sử dụng để thiết kế giao diện. Các phần tử của biểu mẫu như nhập văn bản, radio, chọn, v.v. có thể được sử dụng một cách thích hợp. Dữ liệu do người dùng nhập vào được gửi dưới dạng thông báo yêu cầu Http tới tập lệnh phía máy chủ bằng phương thức GET hoặc POST.
Tập lệnh phía máy chủ phải tạo lại các phần tử biểu mẫu từ dữ liệu yêu cầu http. Vì vậy, trong hiệu ứng này, các phần tử biểu mẫu phải được xác định hai lần - một lần trong HTML và một lần nữa trong tập lệnh phía máy chủ.
Một nhược điểm khác của việc sử dụng biểu mẫu HTML là rất khó (nếu không muốn nói là không thể) để hiển thị động các thành phần biểu mẫu. Bản thân HTML không cung cấp cách nào để xác thực đầu vào của người dùng.
ToscaWidgets2
TurboGears dựa trên ToscaWidgets2, một thư viện xác thực và kết xuất biểu mẫu linh hoạt. Sử dụng ToscaWidgets, chúng tôi có thể xác định các trường biểu mẫu trong tập lệnh Python của mình và hiển thị chúng bằng mẫu HTML. Cũng có thể áp dụng xác thực cho trường tw2.
Thư viện ToscaWidgets là một tập hợp của nhiều mô-đun. Một số mô-đun quan trọng được liệt kê dưới đây:
tw2.core- Nó cung cấp chức năng cốt lõi. Các widget trong mô-đun này không có nghĩa là có sẵn cho người dùng cuối.
tw2.forms- Đây là một thư viện biểu mẫu cơ bản. Nó chứa các widget cho các trường, tập trường và biểu mẫu.
tw2.dynforms - Điều này chứa chức năng biểu mẫu động.
tw2.sqla - Đây là một giao diện cho cơ sở dữ liệu SQLAlchemy.
tw2.forms
Nó chứa một lớp Biểu mẫu, hoạt động như một cơ sở cho các biểu mẫu tùy chỉnh. Có một lớp TableForm hữu ích trong việc hiển thị các trường trong bảng hai cột. ListForm trình bày các trường của nó trong một danh sách không có thứ tự.
Sr.No. | Trường & Mô tả |
---|---|
1 | TextField Trường nhập văn bản một dòng |
2 | TextArea Trường nhập văn bản nhiều dòng |
3 | CheckBox Trình bày một hộp hình chữ nhật có thể kiểm tra với nhãn |
4 | CheckBoxList Nhiều hộp kiểm pf nhóm có thể chọn |
5 | RadioButton Nút chuyển đổi để chọn / bỏ chọn |
6 | RadioButtonList Nhóm các nút Radio loại trừ lẫn nhau |
7 | PasswordField Tương tự như Textfield nhưng các phím nhập không được tiết lộ |
số 8 | CalendarDatePicker Cho phép người dùng chọn ngày |
9 | SubmitButton Nút để gửi biểu mẫu |
10 | ImageButton Nút có thể nhấp với hình ảnh ở trên cùng |
11 | SingleSelectField Cho phép chọn một mục từ danh sách |
12 | MultipleSelectField Cho phép chọn nhiều mục từ danh sách |
13 | FileField Trường tải tệp lên |
14 | EmailField Trường nhập email |
15 | URLField Một trường đầu vào để nhập URL |
16 | NumberField Một hộp quay số |
17 | RangeField Một thanh trượt số |
Trong ví dụ sau, một biểu mẫu sử dụng một số widget này được xây dựng. Trong khi hầu hết các widget này được định nghĩa trong tw2.forms, CalendarDateField được định nghĩa trong mô-đun tw2.Dynforms. Do đó, cả hai mô-đun này cùng với tw2.core đều được nhập ngay từ đầu -
import tw2.core as twc
import tw2.forms as twf
import tw2.dynforms as twd
Biểu mẫu ToscaWidgets là một lớp bắt nguồn từ tw2.forms.formlớp cơ sở. Các widget bắt buộc được đặt bên trong một đối tượng Layout. Trong ví dụ này,TableLayoutĐược sử dụng. Các Widget được hiển thị trong một bảng hai cột. Cột đầu tiên hiển thị chú thích và cột thứ hai hiển thị trường đầu vào hoặc lựa chọn.
Một đối tượng TextField được tạo bằng cách sử dụng hàm tạo sau:
twf.TextField(size, value = None)
Nếu không được đề cập, đối tượng TextField có kích thước mặc định và ban đầu là trống. Trong khi khai báo đối tượng TextArea, số lượng hàng và cột có thể được đề cập.
twf.TextArea("",rows = 5, cols = 30)
Đối tượng NumberField là một TextField chỉ có thể chấp nhận các chữ số. Mũi tên lên và xuống được tạo trên đường viền bên phải để tăng hoặc giảm số lượng bên trong nó. Giá trị ban đầu cũng có thể được chỉ định như một đối số trong phương thức khởi tạo.
twf.NumberField(value)
Ngay bên phải của hộp CalendarDatePicker, một nút lịch được hiển thị. Khi được nhấn, một bộ chọn ngày sẽ bật lên. Người dùng có thể nhập ngày vào hộp theo cách thủ công hoặc chọn từ bộ chọn ngày.
twd.CalendarDatePicker()
Đối tượng EmailField trình bày một Trường văn bản, nhưng văn bản trong đó phải ở định dạng email.
EmailID = twf.EmailField()
Biểu mẫu sau đây cũng có một RadioButtonList. Hàm khởi tạo của lớp này chứa một đối tượng Danh sách như một giá trị của tham số tùy chọn. Nút Radio cho mỗi tùy chọn sẽ được hiển thị. Lựa chọn mặc định được chỉ định với tham số giá trị.
twf.RadioButtonList(options = ["option1","option2"],value = option1)
Hộp kiểm CheckBoxList hiển thị các hộp kiểm cho từng tùy chọn trong danh sách.
twf.CheckBoxList(options = [option1, option2, option3])
Danh sách thả xuống được gọi là SingleSelectfield trong thư viện ToscaWidgets này. Các mục trong đối tượng Danh sách tương ứng với tham số tùy chọn tạo thành danh sách thả xuống. Chú thích hiển thị được đặt làm giá trị của tham số prompt_text.
twf.SingleSelectField(prompt_text = 'text', options=['item1', 'item2', 'item3'])
Theo mặc định, biểu mẫu hiển thị nút Gửi với chú thích là 'lưu'. Để hiển thị một chú thích khác, hãy tạo một đối tượng SubmitButton và chỉ định nó làm tham số giá trị.
twf.SubmitButton(value = 'Submit')
Biểu mẫu được gửi đến một URL, được chỉ định làm giá trị của tham số hành động của biểu mẫu. Theo mặc định, dữ liệu biểu mẫu được gửi bằng phương thức http POST.
action = 'URL'
Trong đoạn mã sau, một biểu mẫu có tên là AdmissionForm được thiết kế bằng cách sử dụng các widget được giải thích ở trên. Thêm mã này trong root.py trước lớp 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')
Bây giờ hãy lưu mã này bên dưới dưới dạng twform.html trong thư mục mẫu -
<!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>
Trong lớp RootController (trong root.py), thêm hàm điều khiển sau:
@expose('hello.templates.twform')
def twform(self, *args, **kw):
return dict(page = 'twform', form = MovieForm)
Trong lớp AdmissionForm, chúng ta có stipulated/save_formdưới dạng URL hành động. Do đó thêmsave_form() chức năng trong RootController.
@expose()
def save_movie(self, **kw):
return str(kw)
Đảm bảo rằng máy chủ đang chạy (sử dụng phục vụ hộp số). Đi vàohttp://localhost:8080/twform trong trình duyệt.
Nhấn nút gửi sẽ đăng dữ liệu này lên save_form() URL, sẽ hiển thị dữ liệu biểu mẫu dưới dạng một đối tượng từ điển.
{
'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'
}
Một thư viện widget Biểu mẫu tốt phải có tính năng xác thực đầu vào. Ví dụ: người dùng phải nhập dữ liệu vào trường bắt buộc hoặc xác minh xem trường email có chứa email hợp lệ hay không mà không cần dùng đến bất kỳ phương tiện lập trình nào khác (như hàm JavaScript) để xác thực.
Các phiên bản đầu tiên của ToscaWidgets Forms Library được sử dụng để dựa vào mô-đun FormEncode để hỗ trợ xác thực. ToscaWidgets2 hiện có hỗ trợ xác thực tích hợp sẵn trong mô-đun tw2.core. Tuy nhiên, vẫn có thể sử dụng các kỹ thuật xác thực FormEncode.
Để xác thực biểu mẫu ToscaWidgets, trình trang trí @validate được sử dụng.
@validate(form, error_handler, validators)
Các ’form’ là đối tượng biểu mẫu ToscaWidgets cần được xác thực.
Các ‘error-handler’ là phương thức bộ điều khiển được sử dụng để xử lý các lỗi biểu mẫu.
Các ‘validators’ là một đối tượng từ điển chứa trình xác thực FormEncode.
Các loại trình xác thực
Mô-đun tw2.core chứa một lớp trình xác thực mà từ đó các trình xác nhận khác được kế thừa. Cũng có thể thiết kế trình xác thực tùy chỉnh dựa trên nó. Một số trình xác thực quan trọng được mô tả dưới đây:
LengthValidator- Kiểm tra xem một giá trị có độ dài quy định hay không. Giới hạn tối thiểu và tối đa được xác định với các tham số tối thiểu và tối đa. Thông báo tùy chỉnh cho độ dài dưới và trên tối thiểu và tối đa có thể được chỉ định dưới dạng tham số tooshort và toolong.
tw2.core.LengthValidator(min = minval, max = maxval,
msgs = { 'tooshort': (‘message for short length’),
'toolong': (‘message for long length)})
RangeValidator- Thường được sử dụng cùng với RangeField. Nó hữu ích để xác thực giá trị của một trường số trong giới hạn tối thiểu và tối đa. Thông báo cho các tham số tooshort và toolong có thể được tùy chỉnh.
tw2.core.RangeValidator(min = minval, max = maxval,
msgs = { 'tooshort': (‘message for short length’),
'toolong': (‘message for long length)})
IntValidator- Lớp này có nguồn gốc từ RangeValidator. Điều này thường được sử dụng để xác thực nếu đầu vào trong trường văn bản bình thường có chứa dữ liệu số nguyên. Có thể đặt giới hạn tối thiểu và tối đa cũng như thông báo lỗi. Ngoài ra, thông báo lỗi cho đầu vào không phải số nguyên có thể được chỉ định dưới dạng tham số 'notint'.
tw2.core.IntValidator(msgs = {‘notint’:’Must be Integer’})
OneOfValidator - Trình xác thực này buộc người dùng chỉ chọn một giá trị từ các tùy chọn có sẵn trong danh sách.
tw2.core.OneOfValidator(values = [option1, option2,..],
msgs = {‘notinlist’:’Not in List’}}
DateValidator- Rất hữu ích để đảm bảo rằng đầu vào của người dùng là ngày hợp lệ. Định dạng ngày (mặc định là YMD) và thông báo lỗi có thể tùy chỉnh. Giới hạn ngày tối thiểu và tối đa cũng có thể được chỉ định. DateTimeValidator cũng có sẵn để xác minh đối tượng của lớp DateTime.
tw2.core.DateValidator(msgs = {format = ’%Y-%m-%d’,
'baddatetime': ('baddate', ('Must follow date format $format_str'))}
EmailValidator- Xác thực đầu vào của người dùng với một địa chỉ email hợp lệ. Lớp này được kế thừa từ một RegexValidator tổng quát hơn.
tw2.core.EmailValidator(msgs = {'badregex': ('bademail',
('Must be a valid email address')) }
UrlValidator- Lớp này cũng được kế thừa từ RegexValidator. Nó xác thực đầu vào của người dùng cho một URL hợp lệ.
tw2.core.UrlValidator(msgs = {'badregex': ('badurl', ('Must be a valid URL’)) }
MatchValidator- Xác nhận xem giá trị của một trường có khớp với trường kia hay không. Điều này đặc biệt hữu ích, khi người dùng được yêu cầu chọn và xác nhận trường mật khẩu. Cách sử dụng điển hình của MatchValidator được hiển thị bên dưới -
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()
Cũng có thể xây dựng một trình xác thực phức hợp, trong đó việc xác thực được mong muốn thành công, nếu bất kỳ kiểm tra nào vượt qua. Trong các trường hợp khác, bạn có thể muốn xác thực thành công, chỉ khi đầu vào vượt qua tất cả các lần kiểm tra. Đối với điều này, tw2.core cung cấp trình xác thực Bất kỳ và Tất cả, là các lớp con của CompoundValidator có thể mở rộng.
TurboGears cung cấp một hệ thống nhắn tin rất tiện lợi để thông báo thông tin cho người dùng một cách không gây khó chịu. Lớp TGFlash trong mô-đun tg cung cấp hỗ trợ cho các tin nhắn nhấp nháy được lưu trữ trong một cookie thuần túy. Lớp này hỗ trợ tìm nạp các tin nhắn flash ở phía máy chủ cũng như phía máy khách thông qua JavaScript.
Các render()phương thức của lớp TGFlash, khi được sử dụng từ chính Python, có thể được gọi từ mẫu để hiển thị thông báo flash. Nếu được sử dụng trên JavaScript, nó cung cấp một đối tượng WebFlash. Nó lộ rapayload() và render() các phương pháp tìm nạp thông báo flash hiện tại và hiển thị nó từ JavaScript.
Khi một dự án TurboGears được tạo bằng cách sử dụng 'quickstart', nó có một mẫu Master.html. Nó chứa định nghĩa của một biến của đối tượng flash đó. Nội dung của thông báo flash này nhận được từ bộ điều khiển thay thế phần giữ chỗ được đánh dấu trong mẫu này.
<py:with vars = "flash = tg.flash_obj.render('flash', use_js = False)">
<div py:if = "flash" py:replace = "Markup(flash)" />
</py:with>
Các tg.flash_obj là đối tượng WebFlash, có sẵn bên trong bất kỳ mẫu được kết xuất nào bằng cách bao gồm master.htmlbản mẫu. Đối tượng này cho phép truy xuất thông báo flash hiện tại và hiển thị nó.
Tin nhắn Flash được lưu trữ trong cookie (có tên theo mặc định là webflash) bằng cách sử dụng tg.flash()phương pháp. Thông báo và các tham số trạng thái sau đó được chuyển đến nó.
tg.flash('Message', 'status')
Nếu phương thức được gọi là flash thực hiện chuyển hướng, thì flash sẽ hiển thị bên trong trang được chuyển hướng. Nếu phương pháp này trực tiếp hiển thị một mẫu, thì đèn flash sẽ hiển thị bên trong chính mẫu đó.
Giao diện của tin nhắn flash có thể được tùy chỉnh bằng cách áp dụng kiểu CSS cho mã trạng thái. Một dự án 'bắt đầu nhanh' chứa mã lỗi, cảnh báo, thông tin và mã trạng thái ổn được tùy chỉnh bởi biểu định kiểu public / css / style.css. Nhiều mã trạng thái với các kiểu cũng có thể được thêm vào.
#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;
}
Biểu định kiểu bên ngoài này cần được bao gồm trong mẫu -
<link rel = "stylesheet" type = "text/css" media = "screen"
href = "${tg.url('/css/style.css')}" />
Có thể đạt được cấu hình của bất kỳ hỗ trợ tin nhắn Flash nào bằng cách thiết lập các tham số cho phương thức config () của đối tượng TGFlash hoặc trong app_cfg.py (trong thư mục config). Các thông số có thể cấu hình là -
Sr.No. | Thông số & Mô tả |
---|---|
1 | flash.cookie_name Tên của cookie được sử dụng để lưu trữ tin nhắn flash. Mặc định làwebflash. |
2 | flash.default_status Trạng thái tin nhắn mặc định nếu không được chỉ định (ok theo mặc định) |
3 | flash.template Được sử dụng như flash template khi kết xuất. |
4 | flash.allow_html Lượt đi on/off escaping in flash messages, HTML mặc định không được phép. |
5 | flash.js_call Mã JavaScript sẽ được chạy khi hiển thị flash từ JavaScript. Mặc định làwebflash.render() |
6 | flash.js_template string.Template ví dụ được sử dụng để thay thế hỗ trợ JavaScript đầy đủ cho các tin nhắn flash. |
pop_payload() - chức năng fetches current flash message, statusvà thông tin liên quan. Nhận được thông báo flash sẽ xóa cookie.
render(container_id, use_js=True) - Hiển thị thông báo flash bên trong mẫu hoặc cung cấp hỗ trợ Javascript cho chúng.
container_id là DIV nơi thông báo sẽ được hiển thị, trong khi use_js chuyển đổi giữa hiển thị flash dưới dạng HTML hoặc để sử dụng JavaScript.
status - Chỉ nhận trạng thái flash hiện tại, nhận trạng thái flash sẽ xóa cookie.
message - Chỉ nhận tin nhắn flash hiện tại, nhận tin nhắn flash sẽ xóa cookie.
Làm thế nào để tạo một tin nhắn Flash đơn giản?
Trong ví dụ sau, một phương thức flash () được cung cấp trong lớp bộ điều khiển gốc. Nó gọi một thông báo flash () được hiển thị cho mẫu tiếp xúc, 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 {}
Mã để làm flash.html trong thư mục mẫu như sau
<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>
Khởi động máy chủ và nhập http://localhost:8080/flash?user=MVL trong trình duyệt
Thay đổi URL thành http://localhost:8080/flash và xem thông báo flash được định dạng khác nhau theo định nghĩa trong style.css
Nó thường được yêu cầu giữ dữ liệu duyệt đơn giản được đính kèm vào trình duyệt của người dùng. Phiên là kỹ thuật được sử dụng phổ biến nhất. Phiên đại diện cho dữ liệu không cần được lưu trữ ở dạng lâu dài hơn như tệp đĩa hoặc cơ sở dữ liệu.
Tuy nhiên, sessiondata trong TurboGears có thể được hỗ trợ bởi hệ thống tệp, cơ sở dữ liệu hoặc các giá trị cookie được băm. Một lượng nhỏ dữ liệu phiên thường được lưu trong cookie, nhưng đối với khối lượng dữ liệu phiên lớn hơn, MemCache được sử dụng.
MemCache là một daemon cấp hệ thống. Nó cung cấp quyền truy cập nhanh vào dữ liệu được lưu trong bộ nhớ cache và có khả năng mở rộng cực kỳ cao. Tuy nhiên, nó chỉ được thiết kế để sử dụng trên các máy chủ an toàn và do đó phải được duy trì và bảo mật bởi sysadmin.
Beaker trong quản lý phiên
TurboGears sử dụng Beaker để quản lý phiên. Theo mặc định, một dự án được khởi động nhanh bằng hộp số được định cấu hình để sử dụng cookie được băm để lưu trữ dữ liệu phiên.
Mỗi khi khách hàng kết nối, phần mềm trung gian phiên (Beaker) sẽ kiểm tra cookie bằng cách sử dụng tên cookie đã được xác định trong tệp cấu hình. Nếu không tìm thấy cookie, cookie sẽ được đặt trong trình duyệt. Trong tất cả các lần truy cập tiếp theo, phần mềm trung gian sẽ tìm thấy cookie và sử dụng nó.
Để cho phép quản lý phiên, lớp phiên phải được kết hợp trong dự án bằng cách sau câu lệnh nhập:
from tg import session
Để lưu dữ liệu trong một biến phiên -
session[‘key’] = value
session.save()
Để truy xuất biến phiên -
return session[‘key’]
Lưu ý rằng bạn cần lưu phiên một cách rõ ràng để các khóa của bạn được lưu trữ trong phiên đó.
Các delete() phương thức của đối tượng phiên sẽ xóa tất cả các phiên người dùng -
session.delete()
Mặc dù thông thường không phải xóa tất cả các phiên người dùng trên bất kỳ môi trường sản xuất cụ thể nào, nhưng bạn thường sẽ làm điều đó để dọn dẹp sau khi thực hiện xong các bài kiểm tra chức năng hoặc khả năng sử dụng.
Dưới đây là một ví dụ đơn giản để minh họa các phiên. Lớp RootController có mộtsetsession() phương thức đặt một biến phiên.
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>"
Đi vào http://localhost:8080/setsession
Một liên kết trong trình duyệt dẫn đến http://localhost:8080/getsession lấy và hiển thị biến phiên -
Để nâng cao hiệu suất của một ứng dụng web, đặc biệt là nếu nó liên quan đến các hoạt động dài, các kỹ thuật bộ nhớ đệm được sử dụng. TurboGears cung cấp hai loại kỹ thuật bộ nhớ đệm:
Whole-page Caching
Nó hoạt động ở cấp giao thức HTTP để tránh toàn bộ yêu cầu đến máy chủ bằng cách trình duyệt của người dùng hoặc máy chủ proxy trung gian (chẳng hạn như Squid) chặn yêu cầu và trả về bản sao được lưu trong bộ nhớ cache của tệp.
Application-level Caching
Điều này hoạt động trong máy chủ ứng dụng để lưu vào bộ nhớ cache các giá trị đã tính toán, thường là kết quả của các truy vấn cơ sở dữ liệu phức tạp, để các yêu cầu trong tương lai có thể tránh phải tính toán lại các giá trị. Đối với các ứng dụng web, bộ nhớ đệm cấp ứng dụng cung cấp một cách linh hoạt để lưu vào bộ nhớ cache kết quả của các truy vấn phức tạp để tổng tải của một phương pháp bộ điều khiển nhất định có thể được giảm xuống một số truy vấn dành riêng cho người dùng hoặc theo trường hợp cụ thể và chi phí hiển thị của một mẫu .
Bộ nhớ đệm cấp ứng dụng
Như đã đề cập trước đó, dự án TurboGears 'khởi động nhanh' được định cấu hình để kích hoạt gói Beaker hỗ trợ bộ nhớ đệm. Beaker hỗ trợ các kết thúc sau được sử dụng để lưu trữ bộ nhớ cache -
memory- Được sử dụng để lưu trữ theo quy trình. Nó là cực kỳ nhanh chóng.
filesystem - lưu trữ trên mỗi quá trình cũng như nhiều quá trình.
DBM database - per-process, multi-process, khá nhanh.
SQLAlchemy database- lưu trữ trên mỗi cơ sở dữ liệu-máy chủ. Chậm hơn so với các tùy chọn đã cho ở trên.
Memcached - bộ nhớ đệm dựa trên bộ nhớ đa máy chủ.
Bộ đệm điều khiển
Đối với bộ nhớ đệm của bộ điều khiển nhanh chóng, cached()trang trí có sẵn. Toàn bộ phần thân bộ điều khiển được lưu vào bộ nhớ đệm tùy thuộc vào các thông số khác nhau của yêu cầu. Định nghĩa củatg.decorators.cached() trang trí như sau
tg.decorators.cached(key, expire, type,
query-args, cache_headers, invalidate_on_startup, cache_response)
Mô tả các thông số như sau:
Sr.No. | Thông số & Mô tả |
---|---|
1 | key Chỉ định các tham số bộ điều khiển được sử dụng để tạo khóa bộ nhớ cache. |
2 | expire Thời gian tính bằng giây trước khi bộ nhớ cache hết hạn, Mặc định là “không bao giờ”. |
3 | Type dbm, memory, file, memcached, hoặc None. |
4 | cache_headers Một loạt tên tiêu đề cho biết tiêu đề phản hồi. |
5 | invalidate_on_startup Nếu Đúng, bộ nhớ cache bị vô hiệu mỗi khi ứng dụng khởi động hoặc được khởi động lại. |
6 | cache_response phản hồi có nên được lưu vào bộ nhớ đệm hay không, mặc định là True. |
Sau đây là một ví dụ về bộ nhớ đệm của bộ điều khiển:
@cached(expire = 100, type = 'memory')
@expose()
def simple(self):
return "This is a cached controller!"
Bộ nhớ đệm cấp mẫu
Công cụ mẫu Genshi lấy mẫu từ bộ nhớ cache nếu nội dung của nó không thay đổi. Kích thước mặc định của bộ đệm này là 25. Theo mặc định, việc tự động tải lại các mẫu là true. Để cải thiện hiệu suất, các cài đặt sau có thể được thực hiện trongapp_cfg.py -
[app:main]
genshi.max_cache_size = 100
auto_reload_templates = false
Để lưu mẫu vào bộ nhớ cache, bạn chỉ cần trả về tg_cache tùy chọn từ bộ điều khiển hiển thị mẫu đã lưu trong bộ nhớ cache.
Tg_cache là một từ điển chấp nhận các khóa sau:
key - Chìa khóa bộ nhớ đệm. Default: Không ai.
expire - bộ nhớ đệm phải tồn tại trong bao lâu. Default: không bao giờ hết hạn
type - bộ nhớ, dbm, memcached. Default: dbm.
Ví dụ sau minh họa bộ nhớ đệm mẫu -
@expose(hello.templates.user')
def user(self, username):
return dict(user = username, tg_cache = dict(key = user, expire = 900))
Mặc dù có thể sử dụng SQL trong ứng dụng TurboGears để thực hiện các hoạt động CRUD trên bất kỳ cơ sở dữ liệu quan hệ nào, nhưng bạn nên sử dụng SQLAlchemy, bộ công cụ Python là một Object Relation Mapper mạnh mẽ cung cấp cho các nhà phát triển ứng dụng toàn bộ sức mạnh và tính linh hoạt của SQL. Ngoài hỗ trợ cho cơ sở dữ liệu dựa trên SQL thông qua SQLAlchemy, TurboGears cũng hỗ trợ cơ sở dữ liệu MongoDB mặc dù Ming. Trong phần này, chức năng của SQLAlchemy được thảo luận.
ORM (Ánh xạ quan hệ đối tượng) là gì?
Hầu hết các nền tảng ngôn ngữ lập trình là hướng đối tượng. Mặt khác, dữ liệu trong máy chủ RDBMS được lưu trữ dưới dạng bảng. Ánh xạ quan hệ đối tượng là một kỹ thuật ánh xạ các tham số đối tượng tới cấu trúc bảng RDBMS bên dưới. API ORM cung cấp các phương thức để thực hiện các hoạt động CRUD mà không cần phải viết các câu lệnh SQL thô.
Khi một dự án TurboGears được tạo bằng lệnh 'khởi động nhanh' từ bộ công cụ hộp số, hỗ trợ SQLAlchemy được bật theo mặc định theo cài đặt cấu hình sau:
config['use_sqlalchemy'] = True
config['sqlalchemy.url'] = 'sqlite:///devdata.db'
Dự án 'bắt đầu nhanh' cũng tạo ra một gói mô hình bên trong nó. Ví dụ, một dự án 'Hello' sẽ có Hello \ hello \ model. Các tệp sau được tạo trong gói này:
__init__.py- Đây là nơi thiết lập quyền truy cập cơ sở dữ liệu. Các đối tượng mô hình của ứng dụng được nhập trong mô-đun này. Nó cũng có một DBSession - một trình quản lý phiên toàn cầu và cũng là một Decl CompareBase, là một lớp cơ sở cho tất cả các lớp mô hình.
auth.py- Đây là nơi các mô hình được sử dụng bởi ngăn xếp xác thực được xác định. Các mô hình cơ sở dữ liệu bổ sung được lưu trữ trong gói này, dưới dạng một mô-đun riêng biệt và được thêm vào __init__.py.
Hãy để chúng tôi thêm một mô hình học sinh sẽ thiết lập một bảng học sinh trong sqlite cơ sở dữ liệu.
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 = '')
Bây giờ hãy thêm mô hình này vào init_model() chức năng bên trong __init__.py.Hàm này đã chứa mô hình xác thực trong đó. Thêm mô hình sinh viên của chúng tôi bên dưới nó.
# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student
Nếu bạn muốn bảng được khởi tạo với một số dữ liệu tại thời điểm thiết lập mô hình, hãy thêm nó vào bootstrap.py trong gói websetup. Thêm các câu lệnh sau vàobootstrap() chức năng.
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()
Các mô hình được khởi tạo bằng cách chạy lệnh cài đặt ứng dụng của hộp số -
gearbox setup-app
Đối tượng phiên của SQLAlchemy quản lý tất cả các hoạt động liên tục của đối tượng ORM.
Các phương thức phiên sau đây thực hiện Thao tác CRUD:
DBSession.add(model object) - Chèn một bản ghi vào bảng ánh xạ.
DBSession.delete(model object) - Xóa bản ghi khỏi bảng.
DBSession.query(model).all() - lấy tất cả các bản ghi từ bảng (tương ứng với một truy vấn SELECT).
Bạn có thể áp dụng bộ lọc cho tập hợp bản ghi đã truy xuất bằng cách sử dụng thuộc tính bộ lọc. Ví dụ, để truy xuất các bản ghi có city = 'Hyderabad' trong bảng sinh viên, hãy sử dụng câu lệnh sau:
DBSession.query(model.student).filter_by(city = ’Hyderabad’).all()
Bây giờ chúng ta sẽ xem cách tương tác với các mô hình thông qua URL bộ điều khiển.
Trước tiên, hãy để chúng tôi thiết kế một biểu mẫu ToscaWidgets để nhập dữ liệu của học sinh
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')
Trong RootController (root.py của ứng dụng Hello), thêm URL ánh xạ chức năng '/ add' sau -
from hello.controllers.studentform import StudentForm
class RootController(BaseController):
@expose('hello.templates.studentform')
def add(self, *args, **kw):
return dict(page='studentform', form = StudentForm)
Lưu mã HTML sau thành studentform.html trong thư mục mẫu -
<!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>
Đi vào http://localhost:8080/addtrong trình duyệt sau khi khởi động máy chủ. Biểu mẫu thông tin sinh viên sau đây sẽ mở ra trong trình duyệt -
Biểu mẫu trên được thiết kế để nộp cho ‘/save_record’URL. Do đó asave_record() chức năng cần được thêm vào root.pyđể phơi bày nó. Dữ liệu từ biểu mẫu sinh viên được hàm này nhận dưới dạngdict()vật. Nó được sử dụng để thêm một bản ghi mới trong mô hình sinh viên cơ bản của bảng sinh viên.
@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")
Xin lưu ý rằng sau khi bổ sung thành công, trình duyệt sẽ được chuyển hướng đến ‘/listrec’ URL. URL này được hiển thị bởi mộtlistrec() function. Hàm này chọn tất cả các bản ghi trong bảng sinh viên và gửi chúng dưới dạng một đối tượng dict tới mẫu studentlist.html. Điều nàylistrec() chức năng như sau:
@expose ("hello.templates.studentlist")
def listrec(self):
entries = DBSession.query(student).all()
return dict(entries = entries)
Mẫu studentlist.html lặp qua đối tượng từ điển mục bằng cách sử dụng chỉ thị py: for. Mẫu studentlist.html như sau:
<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>
Bây giờ hãy truy cập lại http://localhost:8080/addvà nhập dữ liệu vào biểu mẫu. Bằng cách nhấp vào nút gửi, nó sẽ đưa trình duyệt đến studentlist.html. Nó cũng sẽ nhấp nháy thông báo 'bản ghi mới đã được thêm thành công'.
ToscaWidgets chứa một điều khiển DataGrid cung cấp một cách nhanh chóng để trình bày dữ liệu dưới dạng bảng. Đối tượng DataGrid được khai báo như sau:
from tw2.forms import DataGrid
student_grid = DataGrid(fields = [('Name', 'name'),('City', 'city'),
('Address','address'), ('PINCODE', 'pincode')])
Bây giờ, hàm showgrid () truy xuất tất cả các bản ghi trong bảng sinh viên và hiển thị dữ liệu vào mẫu grid.html. Đầu tiên, mã cho hàm showgrid () và sau đó mã grid.html được đưa ra bên dưới:
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>
Dữ liệu dạng bảng sau sẽ được hiển thị khi http://localhost:8080/showlist URL được nhập vào trình duyệt -
TurboGears cung cấp một trình trang trí tiện lợi được gọi là paginate () để phân chia đầu ra trong các trang. Decorator này được kết hợp với decorator (). Trình trang trí @Paginate () lấy đối tượng từ điển của kết quả truy vấn làm đối số. Ngoài ra, số lượng bản ghi trên mỗi trang được quyết định bởi giá trị của thuộc tính items_per_page. Đảm bảo rằng bạn nhập hàm phân trang từ tg.decorators vào mã của mình.
Viết lại hàm listrec () trong root.py như sau:
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)
Các mục trên mỗi trang được đặt thành ba.
Trong mẫu studentlist.html, điều hướng trang được bật bằng cách thêm tmpl_context.paginators.entries.pager () bên dưới chỉ thị py: for. Mã cho mẫu này phải như sau:
<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>
Đi vào http://localhost:8080/listrectrong trình duyệt. Trang đầu tiên của các bản ghi trong bảng được hiển thị. Trên đầu bảng này, các liên kết đến số trang cũng được nhìn thấy.
Cách thêm hỗ trợ phân trang vào Datagrid
Cũng có thể thêm hỗ trợ phân trang vào datagrid. Trong ví dụ sau, datagrid được phân trang được thiết kế để hiển thị nút hành động. Để kích hoạt nút hành động, đối tượng datagrid được xây dựng với mã sau:
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)))) ])
Ở đây nút hành động được liên kết với tham số tên của mỗi hàng trong lưới dữ liệu.
Viết lại showgrid() chức năng như sau -
@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)
Trình duyệt hiển thị lưới dữ liệu được phân trang như sau:
Bằng cách nhấp vào nút Chỉnh sửa ở hàng thứ ba, nó sẽ chuyển hướng đến URL sau http://localhost:8080/edit?name=Rajesh+Patil
TurboGears cung cấp phần mở rộng tgext.admin, được hỗ trợ bởi tgext.crud và gerx. Sprox này là một gói được sử dụng để tạo các widget web trực tiếp từ lược đồ cơ sở dữ liệu. Điều này có thể được sử dụng để tự động tạo các trang quản trị đơn giản và là bộ công cụ cung cấp năng lượng cho trang / admin trong các ứng dụng mới khởi động nhanh.
Theo mặc định, quản trị viên sẽ cung cấp quyền truy cập được tạo tự động vào tất cả các mô hình được nhập trong các mô hình dự án của bạn / __ init__.py.
Cách tạo quản trị viên TurboGears
Quản trị viên TurboGears mặc định được tạo như một đối tượng của lớp AdminController -
from tgext.admin.controller import AdminController
class RootController(BaseController):
admin = AdminController(model, DBSession, config_type = TGAdminConfig)
Thao tác này tạo quản trị viên cho tất cả các kiểu máy có cấu hình quản trị viên TurboGears mặc định.
Thông qua trình quản lý, một người dùng đã được tạo trong giai đoạn thiết lập. Bây giờ, có thể truy cập vào Quản trị viên TurboGears tạihttp://localhost:8080/adminLần đầu tiên trang này được truy cập, nó sẽ yêu cầu xác thực. Bạn chỉ cần cung cấp tên người dùng và mật khẩu của người dùng mà lệnh setup-app đã tạo cho chúng tôi -
Username: manager
Password: managepass
Để đăng nhập vào dự án bắt đầu nhanh, hãy thêm các chức năng sau vào lớp 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)
Đăng nhập vào ứng dụng 'khởi động nhanh' sau khi khởi động máy chủ và bằng cách truy cập http://localhost:8080/loginvà sau đó nhập thông tin đăng nhập của người quản lý như hiển thị ở trên. Trình duyệt sẽ hiển thị một trang quản trị như hình dưới đây -
Trang hiển thị tất cả các mô hình được tạo trong ứng dụng này. Bạn có thể nhấp vào bất kỳ mô hình nào để xem danh sách các mục nhập trong đó -
Nút 'Mới' ở trên cùng của lưới dữ liệu này cho phép thêm bản ghi. Tương tự, các nút hành động để chỉnh sửa và xóa bản ghi cũng được cung cấp trong cột hành động của lưới dữ liệu này. Một hộp tìm kiếm cũng được hiển thị để chọn các bản ghi có điều kiện.
Ứng dụng TurboGears được tạo bằng cách khởi động nhanh và các tùy chọn ứng dụng của bộ công cụ hộp số, có hỗ trợ ủy quyền và xác thực được bật theo mặc định. Các mô hình được khai báo trong auth.py được thiết lập và khởi tạo theo các giá trị được chỉ định trong bootstrap.py.
Các mô hình sau được khai báo trong auth.py -
Mô hình người dùng
Mô hình Người dùng chứa thiết kế của một bảng tg_user. Bảng này được sử dụng bởi gói repose.who. Gói repose.who này là một thư viện xác thực mạnh mẽ cũng như có thể mở rộng cho các ứng dụng WSGI. Cấu trúc của một mô hình người dùng như sau:
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)
Mô hình nhóm này chứa bảng tg_group định nghĩa. Định nghĩa của nó được đưa ra trong auth.py như sau:
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)
Một quyền mô hình khác cũng được thiết lập, chứa định nghĩa quyền.
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))
Tại thời điểm thiết lập mô hình, dữ liệu sau được thêm vào các bảng này:
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)
Mô hình dự đoán
Mô-đun vị từ trong gói tg chứa các định nghĩa cho bộ kiểm tra vị từ. Vị từ là một điều kiện phải được đáp ứng để người dùng có thể truy cập nguồn được yêu cầu. Vị ngữ hoặc điều kiện như vậy có thể được tạo thành từ nhiều vị từ hơn - những vị ngữ đó được gọi là vị từ ghép. Bộ điều khiển hành động, hoặc bộ điều khiển, có thể chỉ có một vị từ, có thể là đơn hoặc ghép.
Nếu người dùng chưa đăng nhập hoặc không có quyền thích hợp, trình kiểm tra vị từ này ném 401 (HTTP Unauthorized), bị phần mềm trung gian repoze.who bắt để hiển thị trang đăng nhập cho phép người dùng đăng nhập và chuyển hướng người dùng quay lại trang thích hợp khi họ hoàn tất.
Các điều kiện hoặc vị từ khác nhau được xác định trong mô-đun tg.predicates là:
Sr.No. | Mô-đun tg.predicates & Mô tả |
---|---|
1 | All Kiểm tra xem tất cả các vị từ được chỉ định có được đáp ứng không |
2 | Any Kiểm tra xem có đáp ứng ít nhất một trong các vị từ được chỉ định hay không |
3 | is_user Kiểm tra xem tên người dùng của người dùng đã xác thực có phải là tên người dùng được chỉ định không |
4 | in_group Kiểm tra xem người dùng có thuộc nhóm cụ thể hay không. |
5 | in_all_groups Kiểm tra xem người dùng có thuộc tất cả các nhóm được chỉ định hay không. |
6 | in_any_group Kiểm tra xem người dùng có thuộc ít nhất một trong các nhóm được chỉ định hay không. |
7 | is_anonymous Kiểm tra xem người dùng hiện tại có ẩn danh không. |
số 8 | has_permission Kiểm tra xem người dùng hiện tại có quyền được chỉ định hay không. |
9 | has_all_permissions Kiểm tra xem người dùng hiện tại đã được cấp tất cả các quyền được chỉ định chưa. |
10 | has_any_permission Kiểm tra xem người dùng có ít nhất một trong các quyền được chỉ định hay không. |
Ví dụ: nếu bạn có một vị ngữ, grant access user belonging to customers group, thì bạn có thể sử dụng trình kiểm tra vị từ tích hợp sau:
from tg.predicates import in_group
p in_group(‘customers’)
Trình kiểm tra vị từ sau sẽ cấp quyền truy cập cho người dùng 'root' hoặc bất kỳ ai có quyền 'quản lý' -
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 cũng hỗ trợ cơ sở dữ liệu tài liệu MongoDB. Nó sử dụng Ming, một API trình lập bản đồ tài liệu đối tượng. Cách sử dụng của Ming rất giống với SQLAlchemy. Ngôn ngữ truy vấn Ming giúp bạn có thể chuyển dự án TurboGears dựa trên SQLAlchemy sang Ming.
PyMongo là gì
PyMongo là một bản phân phối Python chứa các công cụ để làm việc với MongoDB. Ming mở rộng PyMongo cung cấp -
- Mô hình khai báo
- Xác thực và chuyển đổi giản đồ
- Tiến hóa lược đồ
- Triển khai MongoDB Pure InMemory
- Đơn vị công việc
- Bản đồ nhận dạng
- Mối quan hệ một-nhiều, nhiều-một và nhiều-nhiều
Trước hết, bạn cần tải xuống và cài đặt MongoDB. Bản phân phối mới nhất của MongoDB có thể được tải xuống từhttps://www.mongodb.org/downloads
Trên Windows, khởi động máy chủ MongoDB bằng cách cung cấp tùy chọn -dbpath -
C:\mongodb\bin>Mongod --dbpath d:\mongo
D:\mongo folderđược chỉ định để lưu trữ cơ sở dữ liệu MongoDB. Máy chủ bắt đầu nghe lúchttp://localhost:27017. Bây giờ để khởi động MongoDB shell, hãy sử dụng lệnh sau:
C:\mongodb\bin>Mongo
Môi trường MongoDB của chúng tôi hiện đã sẵn sàng.
Bây giờ, hãy tạo một dự án TurboGears với tùy chọn -ming -
gearbox quickstart --ming Hello
Dự án bắt đầu nhanh này sẽ cung cấp một lớp xác thực và ủy quyền giống như lớp được cung cấp cho phiên bản SQLAlchemy. Ứng dụng này bây giờ sẽ cố gắng kết nối với máy chủ trên cổng 27017 trên máy cục bộ. Tệp development.ini trong thư mục dự án chứa các cài đặt sau:
ming.url = mongodb://localhost:27017/
ming.db = hello
Thiết lập dự án bằng lệnh sau:
Python setup.py develop
Thư mục dự án chứa thư mục con mô hình có các tệp sau:
__init__.py - Đây là nơi databasequyền truy cập được thiết lập. Bộ sưu tập của bạn nênimported into this module. Ví dụ, chúng tôi sẽ thêm bộ sưu tập học sinh trong gói này.
session.py - Tệp này xác định session of your database connection. Bạn sẽ cần nhập dữ liệu này mỗi khi bạn phải khai báoMappedClass để chỉ định phiên thành perform queries.
auth.py - Tệp này sẽ được tạo, nếu bạn có enabled authentication and authorizationtrong phần khởi động nhanh. Nó xác định ba bộ sưu tậprepoze. ai, mà còn dựa vào: Người dùng, Nhóm và Quyền.
Xác định Bộ sưu tập của bạn
Theo mặc định, TurboGears cấu hình Ming ở chế độ khai báo. Điều này tương tự như hỗ trợ khai báo SQLAlchemy và cần mỗi mô hình kế thừa từ lớp MappedClass.
MappedClass yêu cầu phải có một lớp con __mongometa__ bên trong, lớp này cung cấp thêm thông tin chi tiết về tên của tập hợp lưu trữ tài liệu và phiên được sử dụng để lưu trữ tài liệu.
MappedClass cũng chứa định nghĩa của các trường trong tài liệu. Mô-đun odm của Ming có các định nghĩa về các loại thuộc tính trường khác nhau -
- FieldProperty
- ForeignIdProperty
- RelationProperty
Các ming.schema module xác định các kiểu dữ liệu sau:
- 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
Để thêm tập hợp sinh viên trong mô hình này, hãy lưu mã sau dưới dạng student.py trong thư mục hello / models.
Xin chào \ 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 = ''))
Cuối cùng, đưa mô hình này vào hello \ models \ __ init__.py
# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student
Để thiết lập các mô hình này, hãy chạy lệnh hộp số sau:
Gearbox setup-app
Khởi động máy chủ bằng lệnh hộp số sau:
Gearbox serve –reload –debug
Mở trang chủ của ứng dụng này (http://localhost:8080/)và đăng nhập bằng thông tin đăng nhập của người quản lý. Trang quản trị của ứng dụng này sẽ hiển thị danh sách các mô hình được thiết lập. (đăng nhập với tư cách người quản lý, mật khẩu quản lý)
Việc tạo bộ sưu tập cũng có thể được xác minh trong giao diện web MongoDB cũng như MongoDB shell.
ODMSession được sử dụng để thực hiện một số hoạt động cơ sở dữ liệu bằng cách sử dụng các chức năng sau:
- model.query.find()
- model.query.find_and_modify()
- model.remove()
- model.update()
- model.flush()
Thiết kế biểu mẫu ToscoWidget
Bây giờ chúng ta sẽ thiết kế một biểu mẫu ToscoWidget để nhập dữ liệu sinh viên và thêm nó vào bảng bên dưới mô hình sinh viên.
Sau đây là mã để tạo một studentform.py -
Xin chào \ 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')
Trong URL '/ add' của Rootcontroller của ứng dụng gọi hàm add (), hàm này sẽ mở biểu mẫu được thiết kế ở trên trong trình duyệt. Nút gửi của nó sau đó gọi hàm save_record (). Nó truy xuất dữ liệu biểu mẫu và lưu nó trong bảng sinh viên và chuyển hướng ứng dụng đến URL '/ listrec', hiển thị mẫu danh sách sinh viên.
Root.py cho hoạt động này như sau:
Xin chào / 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")
Các mẫu sau được tạo trong thư mục mẫu -
Xin chào \ Template \ 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>
Xin chào \ template \ 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>
Khởi động lại máy chủ và nhập http://localhost:8080/add trong trình duyệt -
Mỗi khi dữ liệu được thêm vào và nhấn nút gửi, danh sách các mục nhập hiện tại sẽ được hiển thị.
Bộ công cụ Hộp số chứa lệnh giàn giáo, rất hữu ích để tạo nhanh các thành phần mới của ứng dụng TurboGears. Một ứng dụng được tạo bởi lệnh khởi động nhanh của hộp số có một mẫu khung trong thư mục mô hình (model.py.template), một thư mục mẫu (template.html.template) và một thư mục bộ điều khiển (controller.py.template). Các tệp '.template' này được sử dụng làm cơ sở để tạo các khung mới cho một ứng dụng
Ví dụ: để tạo một mô hình mới có tên là mymodel, chỉ cần chạy lệnh sau:
gearbox scaffold model mymodel
Lệnh này sẽ tạo model / mymodel.py với lớp newmodel được định nghĩa trong đó.
# -*- 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']
Người dùng hiện có thể thực hiện các sửa đổi trong cấu trúc bảng theo yêu cầu của họ và sau đó nhập nó vào bên trong model/__init__.py để làm cho mô hình có sẵn bên trong ứng dụng.
Để tạo một mô hình, một lớp bộ điều khiển để xử lý nó và một trang chỉ mục tất cả ba thành phần này có thể được tạo đồng thời bằng lệnh sau.
gearbox scaffold model controller template mymodel
Lệnh này sẽ dẫn đến các bộ điều khiển \ mymodel.py trong đó lớp MymodelController được xác định hợp lệ.
# -*- 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')
Để bắt đầu sử dụng bộ điều khiển này, hãy gắn nó vào bên trong ứng dụng RootController của bạn chỉ để xác định một phiên bản của MymodelController. Thêm các dòng này vào bộ điều khiển \ root.py -
From hello.controller.mymodel import MymodelController
class RootController(BaseController): mymodel = MymodelController()
Mẫu giàn giáo mẫu \ mymodel.html cũng sẽ được tạo trong thư mục mẫu. Nó sẽ hoạt động như một trang chỉ mục cho URL '/ mymodel'.
Tạo ra mymodel.html file trong thư mục mẫu sẽ như sau:
<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>
Có ba cách trong TurboGears để cắm các hành vi bên trong các ứng dụng hiện có.
Hook - Đây là một cơ chế có thể xác định một sự kiện và thông báo cho người nghe đã đăng ký khi và khi các sự kiện được phát ra.
Controller Wrapper- Nó nằm giữa TurboGears và Bộ điều khiển, do đó có thể mở rộng bộ điều khiển như một người trang trí. Do đó, nó có thể được gắn vào bất kỳ ứng dụng bộ điều khiển nào của bên thứ ba.
Application Wrapper - Nó tương tự như bất kỳ phần mềm trung gian WSGI nào, nhưng chỉ hoạt động trong ngữ cảnh TurboGears.
Ở đây trong chương này, chúng ta sẽ thảo luận về cách sử dụng hook bên trong một ứng dụng hiện có.
Móc
Hooks là các sự kiện được đăng ký trong tệp cấu hình của ứng dụng app_cfg.py. Bất kỳ bộ điều khiển nào sau đó được kết nối với các sự kiện này bởi người trang trí sự kiện.
Các móc sau được định nghĩa trong TurboGears:
Sr.No. | Móc & Mô tả |
---|---|
1 | Startup() chỉ trên toàn ứng dụng, được gọi khi ứng dụng khởi động. |
2 | shutdown() chỉ trên toàn ứng dụng, được gọi khi ứng dụng thoát. |
3 | configure_new_app ứng dụng mới đã được tạo bởi trình cấu hình ứng dụng. |
4 | before_config(app) chỉ trên toàn ứng dụng, được gọi ngay sau khi tạo ứng dụng, nhưng trước khi thiết lập các tùy chọn và phần mềm trung gian |
5 | after_config(app) chỉ trên toàn ứng dụng, được gọi sau khi hoàn tất thiết lập mọi thứ. |
6 | before_validate Đã gọi trước khi thực hiện xác thực |
7 | before_call Được gọi sau khi xác thực, trước khi gọi phương thức bộ điều khiển thực tế. |
số 8 | before_render Được gọi trước khi hiển thị mẫu bộ điều khiển, đầu ra là giá trị trả về bộ điều khiển. |
9 | after_render Được gọi sau khi hoàn thành kết xuất mẫu bộ điều khiển. |
Đăng ký một Hook
Để mà register a Hook, tạo các chức năng trong app_cfg.py và sau đó đăng ký chúng bằng mã sau:
tg.hooks.register(hookane, function, controller)
Trong đoạn mã sau, móc on_startup, on_shutdown và before_render được đăng ký trong 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)
Hook before_render được đăng ký với một chức năng điều khiển trong Rootcontroller. Thêm mã sau vào bộ điều khiển \ 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')
Khi ứng dụng được phục vụ, thông báo khởi động sẽ hiển thị trong bảng điều khiển.
hello, startup world
Starting Standard HTTP server on http://127.0.0.1:8080
Khi URL '/' được nhập vào trình duyệt, một thông báo tương ứng với hook before_render sẽ hiển thị trên bảng điều khiển.
system wide before render
Going to render {'page': 'index'}
Các tiện ích mở rộng TurboGears được xác định bởi tgext.* package. Bộ công cụ Hộp số cung cấp lệnh tgext để tạo tiện ích mở rộng mẫu. Ví dụ -
gearbox tgext -n myextension
Các tham số tùy chọn khác cho lệnh này là:
--author - tên tác giả gói.
--email - email của tác giả gói.
--licence- giấy phép được sử dụng cho gói. Mặc định là MIT.
--description - Mô tả gói hàng.
--keywords - Từ khóa gói (mặc định: turbogears2.extension).
Thao tác này sẽ tạo một thư mục tgext.myextension, có một phần mở rộng mẫu đơn giản bên trong.
Run the setup.py bên trong thư mục -
Python setup.py install
Các _init_.py tập tin bên trong tgext/myextension thư mục chứa -
Plugme function - Đây là điểm vào của phần mở rộng.
SetupExtension class - khởi tạo tiện ích mở rộng diễn ra ở đây.
On_startup function - bên trong lớp là một hook được đăng ký trên hàm __call__ bên trong lớp.
Phiên bản ngắn gọn của 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!')
Sau khi tiện ích mở rộng được cài đặt, hãy bật nó bằng cách thực hiện các bổ sung sau trong ứng dụng của app_cfg.py tập tin cấu hình.
from tgext.myextension import plugme
plugme(base_config)
Nếu chúng tôi khởi chạy máy chủ bằng lệnh máy chủ hộp số, thông báo về tiện ích mở rộng mới được đăng ký có thể được xem trên bảng điều khiển bằng cách sau:
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
Nếu tiện ích mở rộng của bạn cần hiển thị các mô hình và bộ điều khiển, bạn có thể muốn xem Pluggable Applications, nhằm tạo ra các ứng dụng Turbogears có thể tái sử dụng có thể được cắm vào bên trong các ứng dụng khác để mở rộng các tính năng của chúng.
Sử dụng lệnh hộp số sau để tạo một ứng dụng có thể cắm được -
gearbox quickstart-pluggable plugtest
Các ứng dụng có thể cắm được này có thể định nghĩa riêng của chúng -
Controllers - sẽ được tự động gắn kết khi ứng dụng bị xóa.
Models - sẽ có sẵn bên trong và bên ngoài ứng dụng được cắm.
Helpers - có thể tự động hiển thị trong đối tượng 'H' trong một mẫu ứng dụng.
Bootstrap - sẽ được thực thi khi setup-app được gọi.
Statics - sẽ có sẵn tại con đường riêng của họ.
Cài đặt ứng dụng plugtest này và gắn kết tương tự bằng cách thực hiện các sửa đổi sau trong app_cfg.py.
from tgext.pluggable import plug
plug(base_config, plugtest)
REST là viết tắt của REthuyết trình State Tngười mua chuộc. REST là kiến trúc dựa trên tiêu chuẩn web và sử dụng Giao thức HTTP để giao tiếp dữ liệu. Nó xoay quanh một tài nguyên trong đó mọi thành phần là một tài nguyên và một tài nguyên được truy cập bằng một giao diện chung sử dụng các phương thức chuẩn HTTP. REST lần đầu tiên được giới thiệu bởiRoy Fielding in 2000.
RestController là gì
RestController trong TurboGears cung cấp một cơ chế để truy cập vào phương thức của yêu cầu, không chỉ URL. Mô hình HTTP tiêu chuẩn bao gồm: GET, POST, PUT và DELETE. RestController hỗ trợ những điều này và cũng thêm một số phím tắt để gửi URL giúp hiển thị dữ liệu dưới dạng biểu mẫu và danh sách, dễ dàng hơn một chút cho người dùng.
Để giải thích cách RESTful hoạt động với TurboGears, chúng ta sẽ định nghĩa một dịch vụ web đơn giản hiển thị danh sách sinh viên.
Mã cho mô hình sinh viên được đưa ra dưới đây:
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 = '')
Bây giờ tạo một bộ điều khiển dựa trên RestController và cung cấp một chức năng xem để liệt kê danh sách sinh viên ở định dạng json.
Bộ điều khiển \ 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)
Gắn StudentController này vào RootController của ứng dụng bằng cách kết hợp các dòng sau trong root.py -
from hello.controllers.student import StudentController
class RootController(BaseController):
students = StudentController()
Đi đến http://localhost:8080/students nó sẽ cung cấp danh sách sinh viên của chúng tôi được mã hóa ở định dạng json.
Chúng tôi sử dụng phương pháp post để xác định cách chúng tôi lưu học sinh của mình vào cơ sở dữ liệu. Phương thức này được gọi bất cứ khi nào http://localhost:8080/student url được truy cập bằng yêu cầu ĐĂNG -
@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)
Sử dụng get_one() , chúng tôi có thể hiển thị một mục từ cơ sở dữ liệu cho người dùng -
@expose('json')
def get_one(self, movie_id):
newstudent = DBSession.query(student).get(uid)
return dict(movie = movie)
PUT là phương thức được sử dụng để cập nhật bản ghi hiện có bằng 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)
Mã công việc của delete được đính kèm với phương thức post_delete. Ở đây, chúng tôi thực sự xóa bản ghi khỏi cơ sở dữ liệu, và sau đó chuyển hướng trở lại trang danh sách -
@expose('json')
def post_delete(self, uid, **kw):
newstudent = DBSession.query(student).get(uid)
DBSession.delete(newstudent)
return dict(movie = newstudent.uid)
Để chuyển từ môi trường phát triển sang môi trường sản xuất chính thức, ứng dụng cần được triển khai trên máy chủ web thực. Tùy thuộc vào những gì bạn có, có sẵn các tùy chọn khác nhau để triển khai ứng dụng web TurboGears.
Apache với mod_wsgi
Mod_wsgi là một mô-đun Apache được phát triển bởi Graham Dumpleton. Nó cho phép các chương trình WSGI được phục vụ bằng máy chủ web Apache.
Trước tiên, hãy cài đặt Apache 2.X cho nền tảng của bạn, nếu chưa hoàn tất. Sau khi bạn đã cài đặt Apache, hãy cài đặt mod_wsgi. Tạo và kích hoạt môi trường ảo Python trên máy chủ và cài đặt TurboGears trong đó.
Cài đặt ứng dụng của bạn trong trình giám đốc ứng dụng, sau đó tạo một tập lệnh có tên app.wsgi.
Cấu hình cài đặt Apache như sau:
<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>
Khởi động lại Apache
Kiểu http://www.site1.com/ trên trình duyệt để truy cập ứng dụng.
TurboGears dưới rạp xiếc và Chaussette
Circus là một người quản lý quy trình & ổ cắm. Nó có thể được sử dụng để giám sát và kiểm soát các quy trình và ổ cắm. Khi được ghép nối với máy chủ Chaussette WSGI, nó có thể trở thành một công cụ mạnh mẽ để triển khai ứng dụng của bạn và quản lý bất kỳ quy trình liên quan nào mà ứng dụng của bạn cần.
TurboGears - GoogleAppEngine
Cài đặt Google AppEngine SDK cho Python từ URL sau: https://cloud.google.coms
Cài đặt Google AppEngine trên hệ thống của bạn. Sau đó, mở Bảng điều khiển dành cho nhà phát triển của Google và đăng nhập bằng Tài khoản Google của bạn -https://console.developers.google.com/start
Tạo một dự án mới có tên mytgapp -
Sử dụng Google AppEngine Launcher, tạo một ứng dụng mới có tên mytgapp.
Các tệp sau sẽ được tạo trong thư mục được chỉ định -
- app.yaml
- favicon.ico
- index.yaml
- main.py
Theo mặc định, ứng dụng được tạo dựa trên khung Webapp2. Để xóa phần phụ thuộc này, hãy chỉnh sửa tệp app.yaml và xóa phần sau:
libraries:
- name: webapp2
version: "2.5.2"
Tạo một môi trường ảo tạm thời trong thư mục có tên mytgapp và cài đặt TurboGears. Tạo một ứng dụng TurboGears trong đó. Bây giờ chúng ta có thể tiến hành chỉnh sửamain.py tệp được khởi động bởi AppEngine để chạy ứng dụng của chúng tôi và thực sự viết một ứng dụng TurboGears ở đó.
Thêm các nội dung sau vào 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()
Bây giờ, chạy ứng dụng từ AppEngine Launcher và nhấp vào nút duyệt để xem ứng dụng đó hoạt động bình thường trên localhost.
Chúng tôi đã tạo một dự án có tên mytgapp trong bảng điều khiển dành cho nhà phát triển. Bây giờ hãy nhấp vào nút triển khai trong Trình khởi chạy. Sau khi quá trình triển khai kết thúc,http://mytgapp.appspot.com/ truy cập để xem đơn đăng ký của chúng tôi trực tuyến.