整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Python Web 框架之 Tornado

          Python Web 框架之 Tornado

          .Tornado

          • Tornado:python編寫的web服務器兼web應用框架

          1.1.Tornado的優勢

          • 輕量級web框架
          • 異步非阻塞IO處理方式
          • 出色的抗負載能力
          • 優異的處理性能,不依賴多進程/多線程,一定程度上解決C10K問題
          • WSGI全棧替代產品,推薦同時使用其web框架和HTTP服務器

          1.2.Tornado VS Django

          • Django:重量級web框架,功能大而全,注重高效開發
          • 內置管理后臺
          • 內置封裝完善的ORM操作
          • session功能
          • 后臺管理
          • 缺陷:高耦合
          • Tornado:輕量級web框架,功能少而精,注重性能優越
          • HTTP服務器
          • 異步編程
          • WebSocket
          • 缺陷:入門門檻較高

          2.安裝

          輸入命令:

          pip install tornado
          

          備注:

          Tornado應該運行在類Unix平臺,為了達到最佳的性能和擴展性,僅推薦Linux和BSD(充分利用Linux的epoll工具和BSD的kqueue達到高性能處理的目的)

          3.使用

          3.1.Tornado入門程序 - (一)

          #-*- coding:utf-8 -*-import tornado.webimport tornado.ioloop#定義處理類型class IndexHandler(tornado.web.RequestHandler):
           #添加一個處理get請求方式的方法
           def get(self):
           #向響應中,添加數據
           self.write('好看的皮囊千篇一律,有趣的靈魂萬里挑一。')if __name__=='__main__': #創建一個應用對象
           app=tornado.web.Application([(r'/',IndexHandler)]) #綁定一個監聽端口
           app.listen(8888) #啟動web程序,開始監聽端口的連接
           tornado.ioloop.IOLoop.current().start()
          

          1 .在pycharm中直接運行代碼

          2 .如果是在ubuntu,在命令窗口輸入

          python 文件名.py
          

          使用瀏覽器訪問

          4.Tornado 代碼解析

          4.1.入門程序代碼解析

          • tornado.web:tornado的基礎web框架
          • RequestHandler:封裝對請求處理的所有信息和處理方法
          • get/post/..:封裝對應的請求方式
          • write():封裝響應信息,寫響應信息的一個方法
          • tornado.ioloop:核心io循環模塊,封裝linux的epoll和BSD的kqueue, tornado高性能處理的核心。
          • current()返回當前線程的IOLoop實例對象
          • start()啟動IOLoop實力對象的IO循環,開啟監聽

          4.2.httpserver底層處理

          • httpserver監聽端口
          tornado.httpserver.HTTPServer(app)httpserver.listen(port)
          
          • httpserver實現多進程操作
          tornado.httpserver.HTTPServer(app)
          httpserver.bind(port)
          httpserver.start(0/None/<0/num)
          # -*- coding:utf-8 -*-from tornado.web import Application,RequestHandlerfrom tornado.ioloop import IOLoopfrom tornado.httpserver import HTTPServerclass IndexHandler(RequestHandler):
           def get(self):
           self.write('給自己一點時間,理清所有的荒唐與期望。')if __name__=='__main__':
           app=Application([(r'/',IndexHandler)])
           http_server=HTTPServer(app) #最原始的方式
           http_server.bind(8888)
           http_server.start(1) #啟動Ioloop輪循監聽
           IOLoop.current().start()
          

          同時打開兩個窗口測試發現實現了多進程

          4.3.options配置

          • 全局配置
          tornado.options.define(
           name, default, type, multiple, help)
          
          • 命令行參數轉換
          tornado.options.parse_command_line()
          #-*- coding:utf-8 -*-from tornado.web import RequestHandler,Applicationfrom tornado.ioloop import IOLoopfrom tornado.httpserver import HTTPServerimport tornado.options#定義變量tornado.options.define('port',default=8000,type=int,help="this is the port >for application")class IndexHandler(RequestHandler):
           def get(self):
           self.write('我們既然改變不了規則,那就做到最好')if __name__=='__main__':
           app=Application([(r'/',IndexHandler)])
           tornado.options.parse_command_line()
           http_server=HTTPServer(app)
           http_server.bind(tornado.options.options.port)
           http_server.start(1) #啟動IOLoop輪循監聽
           IOLoop.current().start()
          

          通過命令窗口輸入port來訪問

          通過使用我們命令窗口設定的port進行訪問

          • 配置文件
          #即在當前py文件目錄創建config文件,并在py代碼中加入以下代碼,tornado.options.parse_config_file("./config")
          
          • 配置模塊:跟配置文件類似

          4.4.application配置

          • 程序調試之debug配置
          #自動重啟+取消緩存模板+取消緩存靜態文件+提供追蹤信息tornado.web.Application([(..)], debug=True)
          注:開發之初可以設置debug=True方便調試,開發完畢改為False.
          
          • 路由信息初始化參數配置
          tonado.web.Application([(r””, Handler, {k:v})])def initialize(self, k)
          
          • 路由名稱設置及反解析
          #名稱設置tornado.web.Application([
           url(r””, handler, {k,v}, name=“”)
          ])#反解析操作reverse_url(name)
          

          實例

          # -*- coding:utf-8 -*-from tornado.web import Application, RequestHandler, urlfrom tornado.ioloop import IOLoopfrom tornado.httpserver import HTTPServerclass IndexHandler(RequestHandler):
           def get(self):
           self.write("<a href='"+self.reverse_url("login")+"'>用戶登錄</a>")class RegistHandler(RequestHandler):
           def initialize(self, title):
           self.title=title def get(self):
           self.write("注冊業務處理:" + str(self.title))class LoginHandler(RequestHandler):
           def get(self):
           self.write("用戶登錄頁面展示") def post(self):
           self.write("用戶登錄功能處理")if __name__=="__main__":
           app=Application(
           [
           (r"/", IndexHandler),
           (r"/regist", RegistHandler, {"title": "會員注冊"}),
           url(r"/login", LoginHandler, name="login"),
           ]
           )
           http_server=HTTPServer(app)
           http_server.listen(8000)
           IOLoop.current().start()
          

          4.5.參數傳遞

          • get方式傳遞參數
          get_query_arguments(name,default=_ARG_DEFAULT,strip=True)
          get_query_argument(name ,strip=True)
          
          • post方式傳遞參數
          get_body_arguments(name, default=_ARG_DEFAULT,strip=True)
          get_body_argument(name ,strip=True)
          

          實例

          # -*- coding:utf-8 -*-from tornado.web import Application, RequestHandlerfrom tornado.ioloop import IOLoopfrom tornado.httpserver import HTTPServerclass IndexHandler(RequestHandler):
           def get(self):
           # 獲取get方式傳遞的參數
           username=self.get_query_argument("username")
           usernames=self.get_query_arguments("username") print (username) print (usernames) def post(self):
           # 獲取post方式傳遞的參數
           username=self.get_body_argument("username")
           usernames=self.get_body_arguments("username") print (username) print (usernames)if __name__=="__main__":
           app=Application([(r"/",IndexHandler)])
           app.listen(8000)
           IOLoop.current().start()#網頁運行時需要傳入參數#192.168.11.79:8000/?username=123
          
          • 混合方式
          get_arguments(..)/get_argument(..)
          

          實例

          # -*- coding:utf-8 -*-from tornado.web import Application, RequestHandlerfrom tornado.ioloop import IOLoopclass IndexHandler(RequestHandler):
           def get(self):
           # 獲取get方式的參數
           user=self.get_argument("user")
           print("get方式獲取參數:" + str(user)) def post(self):
           # 獲取post方式的參數
           user=self.get_argument("user")
           print("post方式獲取參數:" + user.encode("utf-8"))if __name__=="__main__":
           app=Application([(r"/", IndexHandler)])
           app.listen(8000)
           IOLoop.current().start()
          
          • 其他參數
          通過request獲取參數數據
          method/host/uri/path/query/version/headers/body/remote_ip/files
          

          實例

          • request/json
          # -*- coding:utf-8 -*-from tornado.web import Application, RequestHandlerfrom tornado.ioloop import IOLoopclass IndexHandler(RequestHandler):
           def get(self):
           print self.request
           json_str={"username": "admin", "password": "123123"}
           self.write(json.dumps(json_str))if __name__=="__main__":
           app=Application([(r"/", IndexHandler)])
           app.listen(8000)
           IOLoop.current().start()
          
          • header

          .add_header() .set_header().set_default_headers()設置響應HTTP頭, 前兩者的不同點在于多次設置同一個項時,.add_header()會疊加參數, 而.set_header()則以最后一次為準..set_default_headers()比較特殊, 是一個空方法, 可根據需要重寫, 作用是在每次請求初始化RequestHandler時設置默認headers

          .

          • .clear_header() .clear().clear_header()

          清除指定的headers, 而.clear()清除.set_default_headers()以外所有的headers設置.

          # add_headerself.add_header('Foo', 'one')self.add_header('Foo', 'two')# set_headerself.set_header('Bar', 'one')self.set_header('Bar', 'two')# HTTP頭的設置結果# Foo → one, two# Bar → two
          

          # -*- coding:utf-8 -*-from tornado.web import Application, RequestHandlerfrom tornado.ioloop import IOLoopclass IndexHandler(RequestHandler):
           def set_default_headers(self):
           # 第二種響應頭設置方式
           print("---------> 響應頭set_default_headers()執行")
           self.set_header("Content-type", "application/json; charset=utf-8")
           self.set_header("qiku", "奇酷信息") def get(self):
           # 第一種操作響應頭的方式:
           # self.set_header("Content-type", "application/json")
           print("---------->get方法執行")
           self.write("{'name':'jerry'}")
           self.set_header("qiku", "qikuedu.com")if __name__=="__main__":
           app=Application([(r"/", IndexHandler)])
           app.listen(8000)
           IOLoop.current().start()
          
          • writerror

          .send_error()用于發送HTTP錯誤頁(狀態碼). 該操作會調用.clear().set_status().write_error()用于清除headers, 設置狀態碼, 發送錯誤頁. 重寫.write_error()可以自定義錯誤頁.

          • # -*- coding:utf-8 -*-from tornado.web import Application, RequestHandlerfrom tornado.ioloop import IOLoopclass IndexHandler(RequestHandler):
           def get(self):
           self.write("hello qikuedu.com")
           self.send_error(404, msg="頁面丟失", info="家里服務器搞對象去了") def write_error(self, status_code, **kwargs):
           self.write("<h1>出錯啦,工程師MM正在趕來的途中...</h1>")
           self.write("<p>錯誤信息:%s</p>" % kwargs["msg"])
           self.write("<p>錯誤描述:%s</p>" % kwargs["info"])if __name__=="__main__":
           app=Application([(r"/", IndexHandler)])
           app.listen(8000)
           IOLoop.current().start()
          

          數據流

          • .write()將數據寫入輸出緩沖區. 如果直接傳入

          dict, 那Tornado會自動將其識別為json, 并把Content-Type設置為application/json, 如果你不想要這個Content-Type, 那么在.write()之后, 調用.set_header()重新設置就好了. 需要注意的是, 如果直接傳入的是list, 考慮到安全問題(json數組會被認為是一段可執行的JavaScript腳本, 且<script src="*/secret.json">可以繞過跨站限制),list將不會被轉換成json.

          • .flush()
          • 將輸出緩沖區的數據寫入socket. 如果設置了callback, 會在完成數據寫入后回調. 需要注意的是, 同一時間只能有一個"等待"的flush callback, 如果"上一次"的flush callback還沒執行, 又來了新的flush, 那么"上一次"的flush callback會被忽略掉.
          • .finish()
          • 完成響應, 結束本次請求. 通常情況下, 請求會在return時自動調用.finish(), 只有在使用了異步裝飾器@asynchronous或其他將._auto_finish設置為False的操作, 才需要手動調用.finish()

          .

          • cookie
          # -*- coding:utf-8 -*-
          from tornado.web import Application, RequestHandlerfrom tornado.ioloop 
          import IOLoop
          class IndexHandler(RequestHandler):
           def get(self):
           self.write("hello qikuedu.com")
           self.set_cookie("loginuser", "admin老王") print self.get_cookie("loginuser") print self.cookiesif __name__=="__main__":
           app=Application([(r"/", IndexHandler)])
           app.listen(8000)
           IOLoop.current().start()
          

          頁面

          • .render()
          • 返回渲染完成的html. 調用后不能再進行輸出操作.
          • .redirect()
          • 重定向, 可以指定3xx重定向狀態碼. 調用后不能再進行輸出操作.
          # 臨時重定向 301self.redirect('/foo')# 永久重定向 302self.redirect('/foo', permanent=True)# 指定狀態碼, 會忽略參數 permanentself.redirect('/foo', status=304)
          
          • redirect

          螞蟻開源,探索、發現、分享主流開源技術框架,搭建開源技術社區,共創美好開源生態!

          Tornado 是一個 Python Web 框架和異步網絡庫,主要用于處理大量網絡請求和數據。Layui 是一個模塊化前端 UI 框架,提供了一系列實用的 UI 組件,如表格、分頁器、彈出框等。

          將 Tornado 與 Layui 結合使用,可以創建一個高效、美觀且功能強大的 Web 應用。以下是一個簡單的示例,展示如何使用 Tornado 和 Layui 創建一個 Web 應用:

          安裝 Tornado 和 Layui

          首先,確保你已經安裝了 Tornado。你可以使用 pip 來安裝它:

          pip install tornado

          創建 Tornado 應用

          使用 Tornado 創建一個簡單的 Web 應用。例如,創建一個 main.py 文件:

          import tornado.ioloop
          
          import tornado.web
          
          from layui import layui_admin
          
          class MainHandler(tornado.web.RequestHandler):
          
          def get(self):
          
          self.write(layui_admin.render('main', 'index')) # 使用 Layui 的渲染方法渲染頁面
          
          def make_app():
          
          return tornado.web.Application([
          
          (r"/", MainHandler),
          
          ])
          
          if __name__=="__main__":
          
          app=make_app()
          
          app.listen(8888) # 監聽端口號,可以根據需要修改
          
          tornado.ioloop.IOLoop.current().start()

          創建 Layui 前端頁面

          在你的項目目錄中創建一個 static 文件夾,并在其中創建一個 layui 子文件夾。將 Layui 的 CSS、JS 和其他資源文件放入 layui 文件夾中。然后,創建一個 HTML 文件(例如 index.html),并在其中引入 Layui 的 CSS 和 JS 文件:

          <!DOCTYPE html>
          <html>
          <!-- 頭部開始 -->
          {% include "public/header.html" %}
          <!-- 頭部結束 -->
          <body>
          
          <!-- 主體部分開始 -->
          <div class="layui-fluid">
              <div class="layui-card">
                  <div class="layui-card-body">
                      <!-- 內容區 -->
                      {% block content %}
                      {% endblock %}
                  </div>
              </div>
          </div>
          <!-- 主體部分結束 -->
          
          <!-- 腳部開始 -->
          {% include "public/footer.html" %}
          <!-- 腳部結束 -->
          </body>
          </html>

          運行 Tornado 應用

          在終端中運行 Tornado 應用:

          python main.py --port=8888 # 根據你的配置修改端口號

          路由文件

          from apps.views.ad import AdIndexHandler, AdListHandler, AdDetailHandler, AdAddHandler, AdUpdateHandler, \
              AdDeleteHandler, AdStatusHandler
          from apps.views.ad_sort import AdSortIndexHandler, AdSortListHandler, AdSortDetailHandler, AdSortAddHandler, \
              AdSortUpdateHandler, AdSortDeleteHandler
          from apps.views.analysis import AnalysisIndexHandler
          from apps.views.city import CityIndexHandler, CityListHandler, CityDetailHandler, CityAddHandler, CityUpdateHandler, \
              CityDeleteHandler, CityGetChildListHandler
          from apps.views.config import ConfigIndexHandler, ConfigListHandler, ConfigDetailHandler, ConfigAddHandler, \
              ConfigUpdateHandler, ConfigDeleteHandler
          from apps.views.config_data import ConfigDataIndexHandler, ConfigDataListHandler, ConfigDataDetailHandler, \
              ConfigDataAddHandler, ConfigDataUpdateHandler, ConfigDataDeleteHandler
          from apps.views.config_web import ConfigWebIndexHandler
          from apps.views.dept import DeptIndexHandler, DeptListHandler, DeptDetailHandler, DeptAddHandler, DeptUpdateHandler, \
              DeptDeleteHandler
          from apps.views.dicts import DictIndexHandler, DictListHandler, DictDetailHandler, DictAddHandler, DictUpdateHandler, \
              DictDeleteHandler
          from apps.views.dicts_data import DictDataIndexHandler, DictDataListHandler, DictDataDetailHandler, DictDataAddHandler, \
              DictDataUpdateHandler, DictDataDeleteHandler
          from apps.views.index import IndexHandler, MainHandler, UserHandler, UpdatePwdHandler, LogoutHandler
          from apps.views.item import ItemIndexHandler, ItemListHandler, ItemDetailHandler, ItemAddHandler, ItemUpdateHandler, \
              ItemDeleteHandler
          from apps.views.item_cate import ItemCateIndexHandler, ItemCateListHandler, ItemCateDetailHandler, ItemCateAddHandler, \
              ItemCateUpdateHandler, ItemCateDeleteHandler, ItemCateGetTreeListHandler
          from apps.views.level import LevelIndexHandler, LevelListHandler, LevelDetailHandler, LevelAddHandler, \
              LevelUpdateHandler, LevelDeleteHandler, LevelStatusHandler, LevelImportHandler, LevelExportHandler
          from apps.views.link import LinkIndexHandler, LinkListHandler, LinkDetailHandler, LinkAddHandler, LinkUpdateHandler, \
              LinkDeleteHandler, LinkStatusHandler
          from apps.views.login import LoginHandler, CaptchaHandler
          from apps.views.member import MemberIndexHandler, MemberListHandler, MemberDetailHandler, MemberAddHandler, \
              MemberUpdateHandler, MemberDeleteHandler, MemberStatusHandler
          from apps.views.member_level import MemberLevelListHandler, MemberLevelDetailHandler, MemberLevelAddHandler, \
              MemberLevelUpdateHandler, MemberLevelDeleteHandler, MemberLevelIndexHandler
          from apps.views.menu import MenuIndexHandler, MenuListHandler, MenuDetailHandler, MenuAddHandler, MenuUpdateHandler, \
              MenuDeleteHandler
          from apps.views.notice import NoticeListHandler, NoticeDetailHandler, NoticeAddHandler, NoticeUpdateHandler, \
              NoticeDeleteHandler, NoticeIndexHandler
          
          from apps.views.position import PositionListHandler, PositionDetailHandler, PositionAddHandler, PositionUpdateHandler, \
              PositionDeleteHandler, PositionStatusHandler, PositionIndexHandler
          
          from apps.views.role import RoleIndexHandler, RoleListHandler, RoleDetailHandler, RoleAddHandler, RoleUpdateHandler, \
              RoleDeleteHandler, RoleStatusHandler
          from apps.views.role_menu import RoleMenuIndexHandler, RoleMenuSaveHandler
          from apps.views.upload import UploadHandler, UploadEditHandler
          from apps.views.user import UserIndexHandler, UserListHandler, UserDetailHandler, UserAddHandler, UserUpdateHandler, \
              UserDeleteHandler, UserStatusHandler, UserResetPwdHandler
          
          # 定義路由集合
          router=list()
          
          # 登錄路由
          def login_router():
              # 路由配置
              r=[
                  (r'/', LoginHandler),
                  (r'/login', LoginHandler),
                  (r'/captcha', CaptchaHandler),
              ]
              # 路由前綴
              login_r=""
              # 路由數組
              login=[(login_r + v[0], v[1]) for v in r]
              print('登錄路由:', login)
              # 返回路由
              return login
          
          
          # 主頁路由
          def index_router():
              # 路由配置
              r=[
                  (r'/', IndexHandler),
                  (r'/index', IndexHandler),
                  (r'/main', MainHandler),
                  (r'/userInfo', UserHandler),
                  (r'/updatePwd', UpdatePwdHandler),
                  (r'/logout', LogoutHandler),
              ]
              # 路由前綴
              index_r=""
              # 路由數組
              index=[(index_r + v[0], v[1]) for v in r]
              print('主頁路由:', index)
              # 返回路由
              return index
          
          
          # 上傳文件路由
          def upload_router():
              # 路由配置
              r=[
                  (r'/uploadImage', UploadHandler),
                  (r'/uploadEditImage', UploadEditHandler),
              ]
              # 路由前綴
              upload_r="/upload"
              # 路由數組
              upload=[(upload_r + v[0], v[1]) for v in r]
              print('上傳文件路由:', upload)
              # 返回路由
              return upload
          
          
          # 職級路由
          def level_router():
              # 路由配置
              r=[
                  (r'/index', LevelIndexHandler),
                  (r'/list?', LevelListHandler),
                  (r'/detail/(\d+)', LevelDetailHandler),
                  (r'/add', LevelAddHandler),
                  (r'/update', LevelUpdateHandler),
                  (r'/delete/(\d+)', LevelDeleteHandler),
                  (r'/status', LevelStatusHandler),
                  (r'/import', LevelImportHandler),
                  (r'/export', LevelExportHandler),
              ]
              # 路由前綴
              level_r="/level"
              # 路由數組
              level=[(level_r + v[0], v[1]) for v in r]
              print('職級路由:', level)
              # 返回路由
              return level
          
          
          # 崗位路由
          def position_router():
              # 路由配置
              r=[
                  (r'/index', PositionIndexHandler),
                  (r'/list?', PositionListHandler),
                  (r'/detail/(\d+)', PositionDetailHandler),
                  (r'/add', PositionAddHandler),
                  (r'/update', PositionUpdateHandler),
                  (r'/delete/(\d+)', PositionDeleteHandler),
                  (r'/status', PositionStatusHandler),
              ]
              # 路由前綴
              position_r="/position"
              # 路由數組
              position=[(position_r + v[0], v[1]) for v in r]
              print('崗位路由:', position)
              # 返回路由
              return position
          
          
          # 部門路由
          def dept_router():
              # 路由配置
              r=[
                  (r'/index', DeptIndexHandler),
                  (r'/list?', DeptListHandler),
                  (r'/detail/(\d+)', DeptDetailHandler),
                  (r'/add', DeptAddHandler),
                  (r'/update', DeptUpdateHandler),
                  (r'/delete/(\d+)', DeptDeleteHandler),
              ]
              # 路由前綴
              dept_r="/dept"
              # 路由數組
              dept=[(dept_r + v[0], v[1]) for v in r]
              print('部門路由:', dept)
              # 返回路由
              return dept
          
          
          # 角色路由
          def role_router():
              # 路由配置
              r=[
                  (r'/index', RoleIndexHandler),
                  (r'/list?', RoleListHandler),
                  (r'/detail/(\d+)', RoleDetailHandler),
                  (r'/add', RoleAddHandler),
                  (r'/update', RoleUpdateHandler),
                  (r'/delete/(\d+)', RoleDeleteHandler),
                  (r'/status', RoleStatusHandler),
              ]
              # 路由前綴
              role_r="/role"
              # 路由數組
              role=[(role_r + v[0], v[1]) for v in r]
              print('角色路由:', role)
              # 返回路由
              return role
          
          
          # 角色菜單路由
          def role_menu_router():
              # 路由配置
              r=[
                  (r'/index/(\d+)', RoleMenuIndexHandler),
                  (r'/save', RoleMenuSaveHandler)
              ]
              # 路由前綴
              role_menu_r="/rolemenu"
              # 路由數組
              role_menu=[(role_menu_r + v[0], v[1]) for v in r]
              print('角色菜單路由:', role_menu)
              # 返回路由
              return role_menu
          
          
          # 菜單路由
          def menu_router():
              # 路由配置
              r=[
                  (r'/index', MenuIndexHandler),
                  (r'/list?', MenuListHandler),
                  (r'/detail/(\d+)', MenuDetailHandler),
                  (r'/add', MenuAddHandler),
                  (r'/update', MenuUpdateHandler),
                  (r'/delete/(\d+)', MenuDeleteHandler),
              ]
              # 路由前綴
              menu_r="/menu"
              # 路由數組
              menu=[(menu_r + v[0], v[1]) for v in r]
              print('角色路由:', menu)
              # 返回路由
              return menu
          
          
          # 用戶路由
          def user_router():
              # 路由配置
              r=[
                  (r'/index', UserIndexHandler),
                  (r'/list?', UserListHandler),
                  (r'/detail/(\d+)', UserDetailHandler),
                  (r'/add', UserAddHandler),
                  (r'/update', UserUpdateHandler),
                  (r'/delete/(\d+)', UserDeleteHandler),
                  (r'/status', UserStatusHandler),
                  (r'/resetPwd', UserResetPwdHandler),
              ]
              # 路由前綴
              user_r="/user"
              # 路由數組
              user=[(user_r + v[0], v[1]) for v in r]
              print('用戶路由:', user)
              # 返回路由
              return user
          
          
          # 用戶路由
          def city_router():
              # 路由配置
              r=[
                  (r'/index', CityIndexHandler),
                  (r'/list?', CityListHandler),
                  (r'/detail/(\d+)', CityDetailHandler),
                  (r'/add', CityAddHandler),
                  (r'/update', CityUpdateHandler),
                  (r'/delete/(\d+)', CityDeleteHandler),
                  (r'/getChildList/(\w+)', CityGetChildListHandler),
              ]
              # 路由前綴
              city_r="/city"
              # 路由數組
              city=[(city_r + v[0], v[1]) for v in r]
              print('城市路由:', city)
              # 返回路由
              return city
          
          
          # 通知路由
          def notice_router():
              # 路由配置
              r=[
                  (r'/index', NoticeIndexHandler),
                  (r'/list?', NoticeListHandler),
                  (r'/detail/(\d+)', NoticeDetailHandler),
                  (r'/add', NoticeAddHandler),
                  (r'/update', NoticeUpdateHandler),
                  (r'/delete/(\d+)', NoticeDeleteHandler),
              ]
              # 路由前綴
              notice_r="/notice"
              # 路由數組
              notice=[(notice_r + v[0], v[1]) for v in r]
              print('通知路由:', notice)
              # 返回路由
              return notice
          
          
          # 站點路由
          def item_router():
              # 路由配置
              r=[
                  (r'/index', ItemIndexHandler),
                  (r'/list?', ItemListHandler),
                  (r'/detail/(\d+)', ItemDetailHandler),
                  (r'/add', ItemAddHandler),
                  (r'/update', ItemUpdateHandler),
                  (r'/delete/(\d+)', ItemDeleteHandler),
              ]
              # 路由前綴
              item_r="/item"
              # 路由數組
              item=[(item_r + v[0], v[1]) for v in r]
              print('站點路由:', item)
              # 返回路由
              return item
          
          
          # 站點路由
          def item_cate_router():
              # 路由配置
              r=[
                  (r'/index', ItemCateIndexHandler),
                  (r'/list?', ItemCateListHandler),
                  (r'/detail/(\d+)', ItemCateDetailHandler),
                  (r'/add', ItemCateAddHandler),
                  (r'/update', ItemCateUpdateHandler),
                  (r'/delete/(\d+)', ItemCateDeleteHandler),
                  (r'/getCateTreeList/(\d+)', ItemCateGetTreeListHandler),
              ]
              # 路由前綴
              item_cate_r="/itemcate"
              # 路由數組
              item_cate=[(item_cate_r + v[0], v[1]) for v in r]
              print('欄目路由:', item_cate)
              # 返回路由
              return item_cate
          
          
          # 友鏈路由
          def link_router():
              # 路由配置
              r=[
                  (r'/index', LinkIndexHandler),
                  (r'/list?', LinkListHandler),
                  (r'/detail/(\d+)', LinkDetailHandler),
                  (r'/add', LinkAddHandler),
                  (r'/update', LinkUpdateHandler),
                  (r'/delete/(\d+)', LinkDeleteHandler),
                  (r'/status', LinkStatusHandler),
              ]
              # 路由前綴
              link_r="/link"
              # 路由數組
              link=[(link_r + v[0], v[1]) for v in r]
              print('友鏈路由:', link)
              # 返回路由
              return link
          
          
          # 廣告位路由
          def ad_sort_router():
              # 路由配置
              r=[
                  (r'/index', AdSortIndexHandler),
                  (r'/list?', AdSortListHandler),
                  (r'/detail/(\d+)', AdSortDetailHandler),
                  (r'/add', AdSortAddHandler),
                  (r'/update', AdSortUpdateHandler),
                  (r'/delete/(\d+)', AdSortDeleteHandler),
              ]
              # 路由前綴
              ad_sort_r="/adsort"
              # 路由數組
              ad_sort=[(ad_sort_r + v[0], v[1]) for v in r]
              print('廣告位路由:', ad_sort)
              # 返回路由
              return ad_sort
          
          
          # 廣告路由
          def ad_router():
              # 路由配置
              r=[
                  (r'/index', AdIndexHandler),
                  (r'/list?', AdListHandler),
                  (r'/detail/(\d+)', AdDetailHandler),
                  (r'/add', AdAddHandler),
                  (r'/update', AdUpdateHandler),
                  (r'/delete/(\d+)', AdDeleteHandler),
                  (r'/status', AdStatusHandler),
              ]
              # 路由前綴
              ad_r="/ad"
              # 路由數組
              ad=[(ad_r + v[0], v[1]) for v in r]
              print('廣告路由:', ad)
              # 返回路由
              return ad
          
          
          # 會員等級路由
          def member_level_router():
              # 路由配置
              r=[
                  (r'/index', MemberLevelIndexHandler),
                  (r'/list?', MemberLevelListHandler),
                  (r'/detail/(\d+)', MemberLevelDetailHandler),
                  (r'/add', MemberLevelAddHandler),
                  (r'/update', MemberLevelUpdateHandler),
                  (r'/delete/(\d+)', MemberLevelDeleteHandler),
              ]
              # 路由前綴
              member_level_r="/memberlevel"
              # 路由數組
              member_level=[(member_level_r + v[0], v[1]) for v in r]
              print('會員等級路由:', member_level)
              # 返回路由
              return member_level
          
          
          # 會員路由
          def member_router():
              # 路由配置
              r=[
                  (r'/index', MemberIndexHandler),
                  (r'/list?', MemberListHandler),
                  (r'/detail/(\d+)', MemberDetailHandler),
                  (r'/add', MemberAddHandler),
                  (r'/update', MemberUpdateHandler),
                  (r'/delete/(\d+)', MemberDeleteHandler),
                  (r'/status', MemberStatusHandler),
              ]
              # 路由前綴
              member_r="/member"
              # 路由數組
              member=[(member_r + v[0], v[1]) for v in r]
              print('會員路由:', member)
              # 返回路由
              return member
          
          
          # 字典路由
          def dict_router():
              # 路由配置
              r=[
                  (r'/index', DictIndexHandler),
                  (r'/list?', DictListHandler),
                  (r'/detail/(\d+)', DictDetailHandler),
                  (r'/add', DictAddHandler),
                  (r'/update', DictUpdateHandler),
                  (r'/delete/(\d+)', DictDeleteHandler),
              ]
              # 路由前綴
              dict_r="/dict"
              # 路由數組
              dict=[(dict_r + v[0], v[1]) for v in r]
              print('字典路由:', dict)
              # 返回路由
              return dict
          
          
          # 字典數據路由
          def dict_data_router():
              # 路由配置
              r=[
                  (r'/index', DictDataIndexHandler),
                  (r'/list?', DictDataListHandler),
                  (r'/detail/(\d+)', DictDataDetailHandler),
                  (r'/add', DictDataAddHandler),
                  (r'/update', DictDataUpdateHandler),
                  (r'/delete/(\d+)', DictDataDeleteHandler),
              ]
              # 路由前綴
              dict_data_r="/dictdata"
              # 路由數組
              dict_data=[(dict_data_r + v[0], v[1]) for v in r]
              print('字典數據路由:', dict_data)
              # 返回路由
              return dict_data
          
          
          # 配置路由
          def config_router():
              # 路由配置
              r=[
                  (r'/index', ConfigIndexHandler),
                  (r'/list?', ConfigListHandler),
                  (r'/detail/(\d+)', ConfigDetailHandler),
                  (r'/add', ConfigAddHandler),
                  (r'/update', ConfigUpdateHandler),
                  (r'/delete/(\d+)', ConfigDeleteHandler),
              ]
              # 路由前綴
              config_r="/config"
              # 路由數組
              config=[(config_r + v[0], v[1]) for v in r]
              print('配置路由:', config)
              # 返回路由
              return config
          
          
          # 配置數據路由
          def config_data_router():
              # 路由配置
              r=[
                  (r'/index', ConfigDataIndexHandler),
                  (r'/list?', ConfigDataListHandler),
                  (r'/detail/(\d+)', ConfigDataDetailHandler),
                  (r'/add', ConfigDataAddHandler),
                  (r'/update', ConfigDataUpdateHandler),
                  (r'/delete/(\d+)', ConfigDataDeleteHandler),
              ]
              # 路由前綴
              config_data_r="/configdata"
              # 路由數組
              config_data=[(config_data_r + v[0], v[1]) for v in r]
              print('配置數據路由:', config_data)
              # 返回路由
              return config_data
          
          
          # 網站配置路由
          def config_web_router():
              # 路由配置
              r=[
                  (r'/index', ConfigWebIndexHandler),
              ]
              # 路由前綴
              config_web_r="/configweb"
              # 路由數組
              config_web=[(config_web_r + v[0], v[1]) for v in r]
              print('網站配置路由:', config_web)
              # 返回路由
              return config_web
          
          
          # 數據統計路由
          def analysis_router():
              # 路由配置
              r=[
                  (r'/index', AnalysisIndexHandler),
              ]
              # 路由前綴
              analysis_r="/analysis"
              # 路由數組
              analysis=[(analysis_r + v[0], v[1]) for v in r]
              print('數據統計路由:', analysis)
              # 返回路由
              return analysis
          
          
          # 初始化路由
          def init_routers():
              print('初始化路由')
              # 登錄路由
              router.extend(login_router())
              # 主頁路由
              router.extend(index_router())
              # 上傳文件路由
              router.extend(upload_router())
              # 職級路由
              router.extend(level_router())
              # 崗位路由
              router.extend(position_router())
              # 部門路由
              router.extend(dept_router())
              # 角色路由
              router.extend(role_router())
              # 角色菜單路由
              router.extend(role_menu_router())
              # 菜單路由
              router.extend(menu_router())
              # 用戶路由
              router.extend(user_router())
              # 城市路由
              router.extend(city_router())
              # 通知路由
              router.extend(notice_router())
              # 站點路由
              router.extend(item_router())
              # 欄目路由
              router.extend(item_cate_router())
              # 友鏈路由
              router.extend(link_router())
              # 廣告位路由
              router.extend(ad_sort_router())
              # 廣告路由
              router.extend(ad_router())
              # 會員等級路由
              router.extend(member_level_router())
              # 會員路由
              router.extend(member_router())
              # 字典路由
              router.extend(dict_router())
              # 字典數據路由
              router.extend(dict_data_router())
              # 配置路由
              router.extend(config_router())
              # 配置數據路由
              router.extend(config_data_router())
              # 網站配置路由
              router.extend(config_web_router())
              # 數據統計路由
              router.extend(analysis_router())
              # 返回結果
              return router
          

          模型文件

          from sqlalchemy import Column, String, Integer
          
          from apps.models.base_db import base_db
          from apps.models.base_model import base_model
          from config.env import DB_PREFIX
          
          
          # 職級模型
          class Level(base_model, base_db):
              # 設置表名
              __tablename__=DB_PREFIX + "level"
              # 職級名稱
              name=Column(String(255), nullable=False, comment="職級名稱")
              # 職級狀態:1-在用 2-停用
              status=Column(Integer, default=0, comment="職級狀態:1-在用 2-停用")
              # 職級排序
              sort=Column(Integer, default=0, comment="職級排序")
          
              # 初始化
              def __init__(self, id, name, status, sort):
                  self.id=id
                  self.name=name
                  self.status=status
                  self.sort=sort
          
              def __repr__(self):
                  return '職級:{}'.format(self.name)
          

          模塊案例

          <!-- 繼承layout.html模板 -->
          {% extends "public/layout.html" %}
          {% block content %}
              <!-- 引入全局自定義組件 -->
              <!-- 功能操作區一 -->
              <form class="layui-form toolbar">
                  <div class="layui-form-item">
                      <div class="layui-inline">
                          <label class="layui-form-label w-auto">職級名稱:</label>
                          <div class="layui-input-inline">
                              <input type="text" name="name" placeholder="請輸入職級名稱" autocomplete="off" class="layui-input">
                          </div>
                      </div>
                      <div class="layui-inline">
                          <div class="layui-input-inline" style="width: auto;">
                              {{ "查詢"|query }}
                              {{ "添加職級"|add("{}") }}
                              {{ "批量刪除"|dall }}
                          </div>
                      </div>
                  </div>
              </form>
          
              <!-- TABLE渲染區 -->
              <table class="layui-hide" id="tableList" lay-filter="tableList"></table>
          
              <!-- 操作功能區二 -->
              <script type="text/html" id="toolBar">
                  {{ "編輯"|edit }}
                  {{ "刪除"|delete }}
              </script>
          {% endblock %}

          案例分享

          DjangoAdmin敏捷開發框架

          使用parse_command_line()后 會影響服務器端日志的輸出。tornado會默認為我們配置logging模塊

          如果想關閉配置用 tornado.options.options.logging=None

          * get請求字符串參數傳遞

          1. get請求傳給后端 key1=value1&key2=value2

          get_query_argument()

          get_query_arguments()

          2. 請求體數據傳遞

          get_body_argument()

          get_body_arguments()

          3.既能接收get請求命令內容也能接收post body提交內容

          get_argument()

          get_arguments()

          * post請求體 表單數據 json

          * 提取url的指定部分

          #無命名子組 按照位置關系傳遞

          (r'/sub-city/(.+)/([a-z]+)',SubjectCityHandler),

          #命名子組按照形參名稱傳遞

          (r'/sub-city/(?P<subject>.+)/(?P<date>\d+)',\

          SubjectDateHandler),

          子組中匹配的內容會自動傳遞個具體的請求處理函數

          * 通過http請求頭提交自定義字段

          import json

          json.loads(s) 將json ---》 python字典

          json.dumps(d) 將python字典 --- 》 json

          ***********************************************

          1. tornado的安裝

          2. settings 的設置

          3. url的配置

          4. 請求數據如何傳遞給tornado處理

          * get ---》參數 key1=1&key2=2

          * post ---》提交數據 (表單提交

          json (request.body) 文件)

          * header ---> 自定義 (request.headers)

          +++++++++++++++++++++++++++++++++++++++++++++++++

          Response 響應

          self.write()

          *將一個字符串返回給客戶端

          *write可以連續多次使用,現將內容寫入緩存,然后再一起response到客戶端

          響應頭 :

          self.set_header()

          *設置一個響應頭

          set_default_headers()

          * 設置默認響應頭

          * 如果具體方法中也設置了和default 相同的header則以具體方法中的為準

          set_status(status_code,reason=None)

          *設置響應碼

          * 響應碼的設置不影響正常的網頁訪問,只影響返回的響應碼和提示內容

          *當設置未定義的響應碼時,必須要加第二個參數

          拋出錯誤

          send_error(status,content)

          * 引發一個錯誤

          * 如果沒有write_error 則直接response一個對應status的默認界面

          *在send_error后不能再write寫入內容

          write_error(self,status_code,**kwargs)

          * 處理send_error 拋出的異常

          * 會自動將send_error拋出的內容傳遞給status_code參數

          Handler中函數

          initialize()

          write_error()

          set_default_headers()

          get() post() head()....

          prepare() : 預處理函數 在執行對應的HTTP請求函數前 執行,無論何種HTTP請求都會引起執行

          on_finish() : 請求處理后執行,主要用來后續資源釋放,日志管理等。此方法中不宜再輸出內容

          執行順序(沒有異常拋出)

          執行了 set_default_error

          執行了initialize

          執行了prepare

          執行了 get請求

          執行了on_finish

          執行順序(拋出異常時)

          執行了 set_default_error

          執行了initialize

          執行了prepare

          執行了 get請求

          執行了 set_default_error

          執行了 write_error

          執行了on_finish

          頁面跳轉

          redirect(url)

          模板

          1. 模板路徑配置 Application中 template_path 賦值表示模板查找路徑

          2. 模板的查找原則 : 找到符合加載的第一個模板

          3. 模板加載函數

          render('index.html',**kwargs)

          * 變量

          render('index.html',a=1,b=2)

          + 如果變量沒定義,會報錯

          列表取值 <p>{{l[2]}}</p>

          字典取值 <p>{{d['title']}}</p>

          object 取值 <p>{{obj.arg}}</p>

          * 表達式

          * 控制語句

          * 函數

          * UIModule

          * 靜態文件

          作業 : 1.總結request 和response 的用法,特別是函 數功能使用

          2.復習mysql中sql語句

          3.參照之前django的界面項目自己用tornado嘗試實現


          主站蜘蛛池模板: 无码精品尤物一区二区三区| 免费一区二区视频| 国产福利一区二区在线视频 | 精品欧美一区二区在线观看| 国产午夜毛片一区二区三区| 波多野结衣一区在线观看| 国产成人精品第一区二区| 无码国产精品一区二区免费式芒果| 一区二区日韩国产精品| 国偷自产视频一区二区久| 激情无码亚洲一区二区三区| 日韩精品无码一区二区三区| 蜜桃AV抽搐高潮一区二区| 中文字幕久久久久一区| 亚洲AⅤ无码一区二区三区在线| 一色一伦一区二区三区| 一区二区乱子伦在线播放| 一区二区不卡视频在线观看| 日本伊人精品一区二区三区| 性色A码一区二区三区天美传媒| 一夲道无码人妻精品一区二区| 日本亚洲国产一区二区三区| 人妻少妇AV无码一区二区| 久久精品一区二区三区中文字幕| 日本中文一区二区三区亚洲| 亚洲AV成人精品日韩一区18p | 无码少妇一区二区性色AV| 久久99热狠狠色精品一区| 日韩一本之道一区中文字幕| 欧洲精品无码一区二区三区在线播放| 99久久精品费精品国产一区二区| 国产精品亚洲综合一区| 亚洲一区爱区精品无码| 日本不卡一区二区三区| 久久久久99人妻一区二区三区| 无码国产精品一区二区免费模式| 乱子伦一区二区三区| 波多野结衣一区二区三区| 在线观看视频一区二区| 国产成人av一区二区三区在线| 麻豆精品一区二区综合av|