序文
最近のpython tordadoフレームワークと、ページ全体のテンプレート、表示やデータアクセスを公開するため、
それはまた、簡単に使用され、ブートストラップより人気の、使いやすく竜巻、と一緒に非常に迅速に小さなケースを実行します。
技術的準備金
パイソン
オブジェクト指向のカプセル化の基礎知識、継承
データベース
mysqlの
フレーム
竜巻、SQLAlchemyの(ORM)、テンプレート
開発ツール
pycharm、クロム
機能開発
A.要件分析
統計は、日付によって逆の順序で、5ページあたりに表示さ
「一時的な無ドッキング統計」:統計的なデータがない場合は、テキストプロンプトがなければなりません
日付別のサポート問い合わせ
ページネーションクエリを表示しません
現在のページ番号が配置されている示唆、ページングクエリをサポートしています、あなたは、任意のページにジャンプすることができます
II。ページプロトタイプ
リミテッドのフロントエンド、個人レベル、既製の部品がたくさんある内部ブートストラップ・テンプレートを探して、半日費やす必要がスクラッチの見積もりから、このようなページを取得するために直接使用することができ、その後、次のレイアウトを変更、スタイルトーンダウン、簡単な操作を行いますページは十分です。
ブートストラップ:https://v3.bootcss.com/components/
竜巻を構築するためのIII。フレームワーク
生徒たちは、Python、直接easy_installを精通しているか、最新の竜巻、SQLAlchemyの、pymysqlモジュールをインストールPIP
bootstrap.js直接ライン上でダウンロードする公式サイトに、当然のことながら、また依存JQuery.jsをブートストラップする必要があります
app.py
静的リソースのパスを設定します。
"static_path": os.path.join(os.path.dirname(__file__), "statics"),
設定テンプレートのパス:
"template_path": os.path.join(os.path.dirname(__file__), 'templates'),
動作モードを設定します。
# 通过脚本传参的方式指定
define("debug", default=1, help="debug mode: 1 to open, 2 to test env, other to production")
"debug": bool(options.debug),
開発は、デバッグモードを、シングルプロセスを開きます。
application.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
プロダクションモード、オープンマルチプロセス:
application.bind(options.port)
application.start(3) # 开启 3 个进程
tornado.ioloop.IOLoop.instance().start()
IV。MySQLの接続
あなたが使用したい買収DBSessionクラス、オブジェクト[セッション= DBSessionを()]を作成をすることができ、
データベースは、特に通常の操作ではない場合、セッションの回復期間は、たとえば、少し長く設定することができます。pool_recycle = 60
# coding: utf-8
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from settings.setting import MYSQL_SERVER, MYSQL_DRIVER, MYSQL_USERNAME, MYSQL_PASSWORD, DB_NAME, DB_CHARSET
# MYSQL_USERNAME = os.getenv('MYSQL_USER') or settings.MYSQL_USERNAME
# MYSQL_PASSWORD =
# 数据库
engine = create_engine("mysql+{driver}://{username}:{password}@{server}/{database}?charset={charset}"
.format(driver=MYSQL_DRIVER,
username=MYSQL_USERNAME,
password=MYSQL_PASSWORD,
server=MYSQL_SERVER,
database=DB_NAME,
charset=DB_CHARSET),
pool_size=20,
max_overflow=100,
pool_recycle=1,
echo=False)
engine.execute("SET NAMES {charset};".format(charset=DB_CHARSET))
MapBase = declarative_base(bind=engine)
DBSession = sessionmaker(bind=engine)
V.処理クラス
基本クラスは、APIの仕様および方法一般的なツールを定義します
まず基底クラスはGlobalBaseHandler、データベースセッション、および取得パラメータパッケージの方法をカプセル化
# 全局基类方法
class GlobalBaseHandler(BaseHandler):
@property
def session(self):
if hasattr(self, "_session"):
return self._session
self._session = DBSession()
return self._session
# 关闭数据库会话
def on_finish(self):
if hasattr(self, "_session"):
self._session.close()
def prepare(self):
pass
お問い合わせ、ページング業務処理クラス
なお:(最初のケース未満);(総ページ数よりも大きいが、総ページ数がゼロです)。
class IllegalStats(GlobalBaseHandler):
def get(self):
"""
获取接入,发布统计数据
:return:
"""
date = self.get_argument("date")
current_page = self.get_argument("current_page") # 当前页
if date:
return self.query_by_date(date)
elif current_page:
return self.query_paginate(current_page)
# 默认返回第一页的数据
else:
return self.query_paginate()
def query_paginate(self, current_page=None):
if current_page is None:
current_page = 1
else:
current_page = int(current_page)
#
page_size = 5 # 分页条数
# 总记录数, 总页数
total_count = IllegalAccessStats.query_count(self.session)
if total_count % page_size == 0:
total_page = int(total_count / page_size)
else:
total_page = int(total_count / page_size) + 1
# 小于第一页
if current_page <= 0:
current_page = 1
# 大于最后一页
if total_page > 0:
if current_page > total_page:
current_page = total_page
else:
current_page = 1
# 当前页的数据
stats_list = IllegalAccessStats.query_paginate(self.session, current_page=current_page, page_size=page_size)
return self.render("statistics.html", stats_list=stats_list, date="", total_count=total_count, total_page=total_page, current_page=current_page)
def query_by_date(self, date):
stats_list = IllegalAccessStats.query_by_date(self.session, date=date)
#
return self.render("statistics.html", stats_list=stats_list, date=date, total_count=None, total_page=None, current_page=None)
VI。レンダリングテンプレート
、HTMLコード内の書き込みのpythonに、と判断すれば、まったく同じ範囲とPythonの構文ステートメントのために、多くの困難がありませんが、ゆっくりとデバッグ出てきたテンプレート、非常に詳細な、非常に良いデバッグをレンダリングエラープロンプトテンプレート、
泥棒、だけでなく、ラベル、だけでなく、論理的なプロセスを記述するために病気を感じます。
statistics.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
width: 默认宽度与设备的宽度相同
initial-scale: 初始的缩放比,为1:1 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>接入&发布统计信息</title>
<!-- Bootstrap -->
<link href="{{static_url('css/bootstrap.min.css')}}" rel="stylesheet">
<script src="{{static_url('js/jquery-2.1.0.min.js')}}"></script>
<script src="{{static_url('js/bootstrap.min.js')}}"></script>
<style type="text/css">
th, td {
text-align: center;
height: 50px;
vertical-align:middle;
}
</style>
</head>
<body>
<div class="container">
<h2 style="text-align: center">接入 & 发布统计信息</h2>
<br>
<br>
<div style="float: left;">
<form class="form-inline" action="/illegal/stats" method="get">
<div class="form-group">
<label for="exampleInputName1">日期</label>
<input type="text" name="date" value="{{ date }}" class="form-control" id="exampleInputName1" placeholder="yyyy-mm-dd" >
</div>
<button type="submit" class="btn btn-default" style="margin: 5px;">查询</button>
</form>
</div>
<br>
<br>
<br>
<br>
<br>
<table border="1" class="table table-bordered table-hover">
<div>
<a class="btn btn-primary" href="/illegal/stats?" style="float: left; margin: 3px;">接入</a>
<a class="btn btn-primary" href="/illegal/stats?" style="position: relative; left: 872px; margin: 3px">发布</a>
</div>
<tr class="access">
<th style="background: #f8efc0; vertical-align:middle">日期</th>
<th style="background: #4cae4c; vertical-align:middle">违法接收</th>
<th style="background: #4cae4c; vertical-align:middle">入库成功</th>
<th style="vertical-align: middle">读取成功</th>
<th style="background: #d9534f; vertical-align:middle">读取失败</th>
<th style="vertical-align: middle">下载成功</th>
<th style="background: #d9534f; vertical-align:middle">下载失败</th>
<th style="vertical-align: middle">写入成功</th>
<th style="background: #d9534f; vertical-align:middle">写入失败</th>
<th style="background: #4cae4c; vertical-align:middle">审核接收</th>
<th style="background: #4cae4c; vertical-align:middle">发布成功</th>
</tr>
{% if len(stats_list) > 0 %}
{% for stats in stats_list %}
<tr>
<td style="vertical-align: middle">{{ stats["date"] }}</td>
<td style="vertical-align: middle">{{ stats["access_received_total"] }}</td>
<td style="vertical-align: middle">{{ stats["access_inserted_total"] }}</td>
<td style="vertical-align: middle">{{ stats["read_success_total"] }}</td>
<td style="vertical-align: middle">{{ stats["read_false_total"] }}</td>
<td style="vertical-align: middle">{{ stats["download_success_total"] }}</td>
<td style="vertical-align: middle">{{ stats["download_false_total"] }}</td>
<td style="vertical-align: middle">{{ stats["write_success_total"] }}</td>
<td style="vertical-align: middle">{{ stats["write_false_total"] }}</td>
<td style="vertical-align: middle">{{ stats["publish_received_total"] }}</td>
<td style="vertical-align: middle">{{ stats["publish_send_total"] }}</td>
</tr>
{% end %}
{% else %}
<tr>
<td colspan="11" style="vertical-align: middle">暂没有对接统计信息</td>
</tr>
{% end %}
</table>
<!-- 查询的时候不显示分页内容-->
{% if total_count is not None or total_page is not None %}
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if current_page == 1 %}
<li class="disabled">
{% end %}
{% if current_page != 1 %}
<li>
{% end %}
<a href="/illegal/stats?current_page={{current_page - 1}}" aria-label="Previous">
<span aria-hidden="false">«</span>
</a>
</li>
{% for page in range(1, total_page + 1) %}
{% if current_page == page %}
<li class="active"><a href="/illegal/stats?current_page={{ page }}">{{ page }}</a></li>
{% end %}
{% if current_page != page %}
<li><a href="/illegal/stats?current_page={{ page }}">{{ page }}</a></li>
{% end %}
{% end %}
{% if current_page == total_page or current_page == 1 %}
<li class="disabled">
{% end %}
{% if current_page != total_page and current_page != 1 %}
<li>
{% end %}
<a href="/illegal/stats?current_page={{current_page + 1}}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
<span style="font-size: 25px;margin-left: 5px;">
共{{ total_count }}条记录,共{{ total_page }}页
</span>
</ul>
</nav>
</div>
{% end %}
</div>
</body>
</html>
要注意
時間を演出テンプレートは、使用し
static_url()
、それ以外のテンプレートは、JSファイルをCSSを見つけることができません、静的リソースは、(静)のパスを取得する関数を適切にページをロードすることはできません。<link href="{{static_url('css/bootstrap.min.css')}}" rel="stylesheet">
<script src="{{static_url('js/jquery-2.1.0.min.js')}}"></script>
<script src="{{static_url('js/bootstrap.min.js')}}"></script>
現在の活性化状態のページへの追加
改善されたプロジェクト
XXX
最後に、プロジェクトのWebアドレス:https://github.com/kaichenkai/TornadoWebApp