本節(jié)我們的主要任務(wù)是把首頁通過bottle的目標(biāo)進(jìn)行渲染展示出來!
起手式
第一步:資源導(dǎo)入項(xiàng)目
把相關(guān)的資源文件拷貝到對應(yīng)目錄文件下,如圖示:

第二步:程序入口代碼編寫
任何程序的啟動(dòng)都是需要一個(gè)入口,后續(xù)啟動(dòng)的時(shí)候也是需要 使用python xxx.py的方式來啟動(dòng)此程序。
#!/usr/bin/evn python
# coding=utf-8
# 導(dǎo)入程序需要的日志包模塊
import logging
# 導(dǎo)入程序需要的Session包模塊
from beaker.middleware import SessionMiddleware
# 導(dǎo)入bottle框架路由,運(yùn)行,模板,程序?qū)嵗?,靜態(tài)文件處理 和 get,post 錯(cuò)誤等處理模塊
from bottle import route, run, TEMPLATE_PATH, default_app, template, static_file, get, error
# 導(dǎo)入異步協(xié)成處理模塊
from gevent import monkey;
# 導(dǎo)入自定義的路由視圖模塊,即URL路徑
from home.routes import *
monkey.patch_all()
# 獲取本腳本所在的路徑
pro_path = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(pro_path)
# 定義assets路徑,即靜態(tài)資源路徑,如css,js,及樣式中用到的圖片等
assets_path = '/'.join((pro_path, 'home/assets'))
# 定義圖片路徑
images_path = '/'.join((pro_path, 'home/images'))
# 定義提供文件下載的路徑
download_path = '/'.join((pro_path, 'home/download'))
# 定義文件上傳存放的路徑
upload_path = '/'.join((pro_path, 'home/upload'))
# 定義模板路徑
TEMPLATE_PATH.append('/'.join((pro_path, 'home/views')))
# 定義日志目錄
log_path = ('/'.join((pro_path, 'log')))
# 定義日志輸出格式
logging.basicConfig(level=logging.ERROR,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename="%s/error_log" % log_path,
filemode='a')
# 設(shè)置session參數(shù)
session_opts = {
'session.type': 'file',
'session.cookei_expires': 3600,
'session.data_dir': '/tmp/sessions',
'sessioni.auto': True
}
@error(404)
def error404(error):
"""定制錯(cuò)誤頁面"""
return template('404')
@route('/assets/<filename:re:.*\.css|.*\.js|.*\.png|.*\.jpg|.*\.gif>')
def server_static(filename):
"""定義/assets/下的靜態(tài)(css,js,圖片)資源路徑"""
return static_file(filename, root=assets_path)
@route('/assets/<filename:re:.*\.ttf|.*\.otf|.*\.eot|.*\.woff|.*\.svg|.*\.map>')
def server_static(filename):
"""定義/assets/字體資源路徑"""
return static_file(filename, root=assets_path)
@get('/favicon.ico')
def favicon():
pass
# 函數(shù)主入口
if __name__ == '__main__':
app_argv = SessionMiddleware(default_app(), session_opts)
run(app=app_argv, host='127.0.0.1', port=8092, debug=True, reloader=True)
else:
application = SessionMiddleware(default_app(), session_opts)
第三步:路由視圖模塊
主要是瀏覽器訪問入口地址,相當(dāng)于控制器文件

#!/usr/bin/evn python
# coding=utf-8
from imp import reload
from bottle import route, template, redirect, request, unicode
from home.data.datahelper import *
import chardet
def get_friendlink():
return get_friendlink_data()
def get_case():
return get_case_data()
@route("/")
def index():
return redirect('index')
@route("/index")
def index():
return template('index', title='首頁', friendlink=get_friendlink())
第四步:首頁HTML頁面劃分
頭部公共模塊:

尾部公共模塊:

尾部包含有一些需要從數(shù)據(jù)庫讀取的信息,就友情連接表數(shù)據(jù)
加載完成后相關(guān)呢JS公共模塊的加載:
<!--[if lt IE 9]>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script>
<script src="assets/js/polyfill/rem.min.js"></script>
<script src="assets/js/polyfill/respond.min.js"></script>
<script src="assets/js/amazeui.legacy.js"></script>
<![endif]-->
<!--[if (gte IE 9)|!(IE)]><!-->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/amazeui.min.js"></script>
<script src="assets/js/app.js"></script>
<!--<![endif]-->
所以首頁劃分了四個(gè)區(qū)域進(jìn)行分別加載,主要通過模塊的
%include('commom.html')
方式來加載

%include('head.html') -------頭部模塊
%include('commom.html')------- 公共腳本加載
%include('footer.html')------- 尾部模塊
%include('index.html')------- 首頁主體內(nèi)容模塊
第五步:首頁HTML頁面劃分
定義首頁渲染入口地址:
@route("/")
def index():
return redirect('index')
@route("/index")
def index():
# friendlink=get_friendlink()從數(shù)據(jù)庫中讀取數(shù)據(jù)信息
return template('index', title='首頁', friendlink=get_friendlink())
第六步:運(yùn)行程序
再App.py右鍵點(diǎn)擊Run app.py,成功渲染出首頁

第七步:解決首頁渲染時(shí)候,當(dāng)前首頁處于選中的狀態(tài)

主要是通過加載
%include('commom.html')------- 公共腳本加載
里面的App.js來控制選中的狀態(tài)

遍歷頁面上所有標(biāo)簽對象,判斷如果當(dāng)前訪問的路徑和當(dāng)前鏈接的地址是一致的話,就設(shè)置它的樣式為選中的狀態(tài)
第八步:從數(shù)據(jù)庫中讀取底部友情鏈接的數(shù)據(jù)
(1)簡單封裝數(shù)據(jù)庫讀寫模塊,需要使用到pymysql模塊,需要通過pip或IDE進(jìn)行此模塊安裝

db.py 源碼:
#!/usr/bin/evn python
# coding=utf-8
import logging
import pymysql
import sys
from config.const import *
def writeDb(sql, db_data=()):
"""
連接mysql數(shù)據(jù)庫(寫),并進(jìn)行寫的操作
"""
try:
conn = pymysql.connect(db=db_name, user=db_user, passwd=db_pass, host=db_ip, port=int(db_port), charset="utf8")
cursor = conn.cursor()
except Exception as e:
logging.error('數(shù)據(jù)庫連接失敗:%s' % e)
return False
try:
# cursor.execute(sql)
cursor.execute(sql, db_data)
conn.commit()
except Exception as e:
# 如果發(fā)生錯(cuò)誤則回滾
conn.rollback()
logging.error('數(shù)據(jù)寫入失敗:%s' % e)
return False
finally:
cursor.close()
conn.close()
return True
def readDb(sql, db_data=()):
"""
連接mysql數(shù)據(jù)庫(從),并進(jìn)行數(shù)據(jù)查詢
"""
try:
conn = pymysql.connect(db=db_name, user=db_user, passwd=db_pass, host=db_ip, port=int(db_port), charset="utf8")
cursor = conn.cursor()
except Exception as e:
logging.error('數(shù)據(jù)庫連接失敗:%s' % e)
return False
try:
cursor.execute(sql, db_data)
data = [dict((cursor.description[i][0], value) for i, value in enumerate(row)) for row in cursor.fetchall()]
except Exception as e:
logging.error('數(shù)據(jù)執(zhí)行失敗:%s' % e)
return False
finally:
cursor.close()
conn.close()
return data
鏈接數(shù)據(jù)庫配置信息const.py:
#!/usr/bin/evn python
# coding=utf-8
### 常量參數(shù)設(shè)置模塊,初始化各個(gè)常量 ###
##################################################################################
### 數(shù)據(jù)庫參數(shù) ###
# 數(shù)據(jù)庫名稱
db_name = 'yunshipei'
# 數(shù)據(jù)庫鏈接用戶名
db_user = 'root'
# 數(shù)據(jù)庫鏈接密碼
db_pass = '111111'
# 數(shù)據(jù)庫鏈接IP地址
db_ip = 'localhost'
# 數(shù)據(jù)庫鏈接端口號
db_port = 3306
(2)寫SQL讀取數(shù)據(jù)庫信息

datahelper.py
#!/usr/bin/evn python
# coding=utf-8
from utils.db import *
# 初始化Redis緩存鏈接
friendlink_data = None
def get_friendlink_data():
"""
從內(nèi)存中讀取友情鏈接數(shù)據(jù),不需要每次都去數(shù)據(jù)庫查
:return:
"""
global friendlink_data
# 將key轉(zhuǎn)換為小寫字母
try:
if not friendlink_data:
sql = "select * from tp_friendlink"
friendlink_data = readDb(sql)
return friendlink_data
except Exception as e:
# log_helper.error('讀緩存失敗:key(' + key + ')' + str(e.args))
friendlink_data = None
return friendlink_data
##################################################################################
(3)再渲染的時(shí)候?qū)肽K進(jìn)行獲取,并輸出到模板中

(4)在模板中接收并處理數(shù)據(jù)
<!-- footer -->
<footer>
<div class="am-container">
<div class="footer-logo">

</div>
<ul class="social-links-list">
<li>
<a target="_blank"
title="qq">
<i class="am-icon-qq am-icon-sm"></i>
</a>
</li>
<li>
<a href="" target="_blank" id="wechat" title="微信">
<i class="am-icon-weixin am-icon-sm"></i>
</a>
</li>
<li>
<a target="_blank" title="新浪微博">
<i class="am-icon-weibo am-icon-sm"></i>
</a>
</li>
</ul>
</ul>
<ul class="friend-links">
<li>友情鏈接:</li>
%if friendlink:
%for col in friendlink:
<li>
<a href="{{col.get('url')}}" target="_blank" title="{{col.get('linkname')}}">{{col.get('linkname')}}</a>
</li>
%end
%end
</ul>
</div>
</footer>
結(jié)束語:
內(nèi)容涵蓋了數(shù)據(jù)庫讀寫,頁面模板中對數(shù)據(jù)處理!
其他系列文章目錄:
python web(bottle)學(xué)習(xí)筆記(1)——前言
python web(bottle)學(xué)習(xí)筆記(2)——python 開發(fā)環(huán)境準(zhǔn)備
python web(bottle)學(xué)習(xí)筆記(3)——‘我愛python’程序動(dòng)起來
python web(bottle)學(xué)習(xí)筆記(4)——實(shí)戰(zhàn)開篇(初步需求準(zhǔn)備)
python web(bottle)學(xué)習(xí)筆記(5)——實(shí)戰(zhàn)開篇(數(shù)據(jù)庫篇)
python web(bottle)學(xué)習(xí)筆記(6)——實(shí)戰(zhàn)編碼(首頁模板渲染)
python web(bottle)學(xué)習(xí)筆記(7)——實(shí)戰(zhàn)編碼(POST提交代理商信息)