整合營銷服務商

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

          免費咨詢熱線:

          Tornado + layui 后臺管理系統

          Tornado + layui 后臺管理系統

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

          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敏捷開發框架

          .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

          ython 的 Tornado 框架,屬于 Python 的一個 Web 框架,是由 Python 編寫的 Web 服務器兼 Web 應用框架。


          Step1:Tornado 是什么

          Tornado 是一個基于 Python 的 Web 服務框架和異步網絡庫。

          最早開發于 FriendFeed 公司,通過利用非阻塞網絡 I/O, Tornado 可以承載成千上萬的活動連接, 完美的實現了長連接, WebSockets, 和其他對于每一位用戶來說需要長連接的程序。


          Step2:Tornado 有什么優勢

          Tornado 具有什么樣的優點,我們為什么要用它?

          ? 輕量級 Web 框架

          ? 異步非阻塞 IO 處理方式

          ? 出色的抗負載能力

          ? 優異的處理性能,不依賴多進程/多線程,一定程度上解決 C10K 問題

          ? WSGI全棧替代產品,推薦同時使用其 Web 框架和 HTTP 服務器


          Step3:Tornado 如何安裝

          pip install tornado 【安裝最新穩定版】
          
          pip install tornado==version 【指定版本安裝】


          Step4:Tornado 核心內容

          4.1 Tornado.Web:Tornado 的基礎 Web 框架

          ? RequestHandler:封裝對請求處理的所有信息和處理方法

          ? get/post/..:封裝對應的請求方式

          ? write():封裝響應信息,寫響應信息的一個方法


          4.2 Tornado.ioloop:核心IO循環模塊,封裝 Linux 的 Epoll 和 BSD 的 kqueue,Tornado 高性能處理的核心。

          ? current()返回當前線程的 IOLoop 實例對象

          ? start()啟動 IOLoop 實力對象的 IO 循環,開啟監聽


          4.3 HttpServer 監聽端口

          ? tornado.httpserver.HTTPServer(app)

          ? httpserver.listen(port)


          4.4 HttpServer 實現多進程操作

          ? tornado.httpserver.HTTPServer(app)

          ? httpserver.bind(port)

          ? httpserver.start(0/None/<0/num)


          Step5:程序結構及說明

          Config.py 配置文件:

          import os
          
          #參數
          param={
              'port':9992,
          }
          
          #配置
          setting={
              "template_path":os.path.join(os.path.dirname(__file__), "templates"),  # 定義視圖頁面地址,放 html文件
              "static_path":os.path.join(os.path.dirname(__file__), "static"),  # 定義靜態模板,放 css,js等文件
              # "debug":True,  # 是否為debug模式
              "autoescape":None,  # 不設置轉義字符
              "autoreload":True,
              "cookie_secret":"QjyutYf0RBW9DRweq4s+TozDU7esgEUTqQy0M6c5II8=",  #安全cookie
              "xsrf_cookies": False,
              "login_url": "/login",
          }


          Application.py 路由配置文件:

          import tornado.web
          import Python_Tornoda.config as config
          from Python_Tornoda.util import mysqldb
          from Python_Tornoda.view.views import MainHandler
          from Python_Tornoda.view.views import LoginHandler
          from tornado.web import StaticFileHandler
          import os
          
          current_path=os.path.dirname(__file__)
          
          class Appliction(tornado.web.Application):
              def __init__(self):
                  handers=[
                      (r"/index/(?P<page>\d*)", MainHandler),
                      (r"/login",LoginHandler),
                      (r'^/(.*?)$', StaticFileHandler,{"path": os.path.join(current_path, "templates"), "default_filename": "main.html"}),
                  ]
                  super(Appliction,self).__init__(handers,**config.setting)


          Views.py視圖函數文件,以“登錄”為示例:

          from Python_Tornoda.util.bussiness import get_data,execute_sql
          from Python_Tornoda.util.Pagination import Pagination
          from tornado.web import RequestHandler
          import time
          
          page_num=5 #每頁展示的條數
          
          #登錄后的主頁
          class MainHandler(RequestHandler):
              def get(self,page):
                  sql1="select id,pms_name,content,status,mark,create_time from tornado_info order by create_time desc"
                  itemList=get_data(sql1)
                  print(page)
                  if(int(page)>len(itemList)//page_num):
                      pages=len(itemList)//page_num+1
                  elif(int(page)<1):
                      pages=1
                  else:
                      pages=int(page)
                  print("ad")
          
                  page_obj=Pagination(pages, len(itemList), page_num)
                  current_list=itemList[page_obj.start:page_obj.end]
                  print("00000000000")
                  print(current_list)
                  str_pageCtrl=page_obj.pageCtrl('/index/')
                  self.render('info.html', items=current_list, current_page=page_obj.currentPage, pageCtrl=str_pageCtrl, )
          
          class LoginHandler(RegisterHandler):
              def set_default_headers(self):
                  print('-----set_default_headers:默認設置----')
                  self.set_header('Content-Type', 'application/json')
          
              def initialize(self):
                  print("-----_initialize 初始化操作-----")
                  print("-----_初始化數據庫連接-----")
                  print("-----_初始化打開文件-----")
          
              def prepare(self):
                  print("-----prepare做一些準備工作-----")
                  print("-----加載配置項-----")
          
              def get(self, *args, **kwargs):
                  print("----get 請求處理---")
                  print("----此處需要根據頁面是get請求來進行處理---")
                  username=self.get_query_argument("username")
                  password=self.get_query_argument("password")
                  self.set_secure_cookie(username,password)
                  if(username=="1" and password=="1"):
                      self.redirect("/index/1")
                  else:
                      self.render('main.html')
          
              def post(self,*args,**kwargs):
                  print("----post 請求處理---")
                  print("----此處需要根據頁面是post請求來進行處理---")
                  username=self.get_body_argument("username")
                  password=self.get_body_argument("password")
                  self.set_secure_cookie(username, password)
                  if (username=="1" and password=="1"):
                      self.redirect("/index/1")
                  else:
                      self.render('main.html')
          
              def write_error(self, status_code: int, **kwargs):
                  if(status_code==500):
                      self.write("the server is wrong")
                  elif(status_code==404):
                      self.write("it's not found")
                  else:
                      self.write("the other of error")
          
              def on_finish(self):
                  print("----處理結束,釋放資源----")
                  print("----釋放db連接----")
                  print("----關閉文件句柄----")
          


          Server.py 程序入口文件:

          import tornado.ioloop
          import tornado.web
          import Python_Tornoda.application as app
          import Python_Tornoda.config as config
          
          if __name__=='__main__':
              print("starting tornado...")
              app=app.Appliction()
              httpServer=tornado.httpserver.HTTPServer(app)
              httpServer.bind(config.param['port'])
              httpServer.start(1)
              tornado.ioloop.IOLoop.current().start()


          Step6:前端代碼

          Login.html:登錄頁代碼

          紅框中可以看得到是用什么方式提交/login

          Index.html: 登錄后的主頁代碼


          Step7:頁面效果

          7.1 登錄頁面展示如下:

          7.2 登錄后主頁面展示如下:

          備注:頁面雖然有些簡陋,但麻雀雖小,五臟俱全。哈哈~


          主站蜘蛛池模板: 日韩一区二区久久久久久| 无码人妻精品一区二区三区9厂| 久久久国产精品亚洲一区 | 亚洲欧美国产国产一区二区三区| 蜜臀Av午夜一区二区三区| 色噜噜一区二区三区| 国产精品视频免费一区二区| 国产精品女同一区二区 | 蜜桃臀无码内射一区二区三区| 中文字幕在线观看一区二区三区| 人妻少妇精品视频三区二区一区| 亚洲一区二区三区久久| 无码少妇一区二区三区浪潮AV| 国产色情一区二区三区在线播放| 亚洲日本一区二区一本一道| 国产成人精品视频一区| 国产一区二区精品久久岳√| 国模精品视频一区二区三区| 在线一区二区观看| 国产aⅴ精品一区二区三区久久| 成人一区专区在线观看| 国产综合精品一区二区| 精品国产一区二区三区久久狼| 无码aⅴ精品一区二区三区| 精品国产一区二区三区在线| 国产伦精品一区二区三区视频小说| 免费高清av一区二区三区| 日本v片免费一区二区三区| 国产精品一区二区三区高清在线| 国产成人一区二区动漫精品| www亚洲精品少妇裸乳一区二区| 精品国产日韩亚洲一区| 久久精品免费一区二区三区| 一区二区三区国产精品 | 一区二区三区波多野结衣| 国产福利电影一区二区三区,免费久久久久久久精 | 国产综合一区二区| 人妻av无码一区二区三区| 伊人久久一区二区三区无码| 韩国精品一区二区三区无码视频| 国产一区二区三区樱花动漫|