python web(bottle)學(xué)習(xí)筆記(6)——實(shí)戰(zhàn)編碼(首頁模板渲染)

本節(jié)我們的主要任務(wù)是把首頁通過bottle的目標(biāo)進(jìn)行渲染展示出來!

起手式

第一步:資源導(dǎo)入項(xiàng)目

把相關(guān)的資源文件拷貝到對應(yīng)目錄文件下,如圖示:

image.png

第二步:程序入口代碼編寫

任何程序的啟動(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)于控制器文件


image.png
#!/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頁面劃分

頭部公共模塊:


image.png

尾部公共模塊:


image.png

尾部包含有一些需要從數(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')

方式來加載

image.png

%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,成功渲染出首頁


image.png

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

image.png

主要是通過加載

%include('commom.html')------- 公共腳本加載

里面的App.js來控制選中的狀態(tài)

image.png

遍歷頁面上所有標(biāo)簽對象,判斷如果當(dāng)前訪問的路徑和當(dāng)前鏈接的地址是一致的話,就設(shè)置它的樣式為選中的狀態(tài)

第八步:從數(shù)據(jù)庫中讀取底部友情鏈接的數(shù)據(jù)

(1)簡單封裝數(shù)據(jù)庫讀寫模塊,需要使用到pymysql模塊,需要通過pip或IDE進(jìn)行此模塊安裝

image.png

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ù)庫信息

image.png

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)行獲取,并輸出到模板中

image.png

(4)在模板中接收并處理數(shù)據(jù)

<!-- footer -->
<footer>
    <div class="am-container">
        <div class="footer-logo">
            ![](assets/images/logo-colorful.png)
        </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提交代理商信息)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容