因爲咱們先後臺系統沒有分開,因此前臺頁面調用接口時,能夠直接使用後臺管理系統已經完成的接口,不事後臺管理系統接口的訪問加上了登陸驗證,因此須要將前臺要用到的接口進行處理,讓它們設置到白名單當中javascript
咱們打開main.py文件,在勾子函數中@hook('before_request')中找到下面代碼html
# 過濾不用作任何操做的路由(即過濾不用進行判斷是否登陸和記錄日誌的url) if path_info in ['/favicon.ico', '/', '/api/verify/']: return
這裏前面已講過,是跳過那些須要權限判斷和進行日誌記錄的訪問,對於後臺上傳的圖片來講,咱們不須要進行日誌記錄和權限判斷,因此在這裏添加上日誌訪問的路由java
# 過濾不用作任何操做的路由(即過濾不用進行判斷是否登陸和記錄日誌的url) if path_info in ['/favicon.ico', '/', '/api/verify/'] or path_info.find('/upload/') > -1: return
path_info是當前客戶端訪問的url,一般url是固定的話,咱們能夠經過in的方式直接進行判斷python
由於上傳的圖片統一存放在/upload/這個目錄中,而訪問圖片的路由是/upload/xxxx/xxxxxxxxx.jpg,每張圖片訪問路徑都不同,新上傳的圖片就會生成新的連接,url是動態變化的,因此咱們使用查找的方式來進行判斷當前url是不是圖片,若是是的話,則不執行下面的操做。ajax
一樣在勾子函數@hook('before_request')中找到下面代碼json
# 過濾不用進行登陸權限判斷的路由(登陸與退出登陸不用檢查是否已經登陸) url_list = ["/api/login/", "/api/logout/"] if path_info in url_list: pass
爲了方便出現問題時及時排查,因此咱們會將客戶端對接口的訪問,以及提交的參數記錄到日誌中,保存一段時間,因此咱們會將一些訪問頻繁但對分析無關的接口添加到前面過濾處理中。api
由於對後臺管理系統操做時,咱們須要對用戶權限進行驗證,因此會在勾子中統一進行驗證用戶是否已經登陸成功。但有一些接口咱們是沒必要要進行驗證的,好比登陸和退出登陸接口,若是它們不排除在外的話,那麼用戶將沒法登陸,由於每次訪問登陸接口都會返回你未登陸不能訪問,這樣就會出現死循環,未登陸不能訪問接口,而不能訪問接口則沒法進行登陸的怪圈當中,因此咱們須要對一些無需登陸就能夠訪問的接口進行例外處理。瀏覽器
對於前臺獲取公司介紹、聯繫咱們、產品分類、產品列表和產品信息的接口,咱們能夠將它們添加到這裏來,進行過濾。服務器
# 過濾不用進行登陸權限判斷的路由(登陸與退出登陸不用檢查是否已經登陸) url_list = ["/api/login/", "/api/logout/", "/api/about/", "/api/contact_us/", "/api/product_class/"] if path_info in url_list or (request.method == 'GET' and path_info.find('/api/product/') > -1): pass
由於咱們使用的是RESTful風格的路由,獲取產品信息、修改產品信息和刪除產品信息路由url是同樣的,只是經過get/put/delete來進行區分,因此咱們在處理時,須要獲取客戶端的提交方式是GET仍是PUT或DELETE,而後進行區分處理。app
咱們知道獲取產品信息的接口路由是:@get('/api/product/<id:int>/') ,它會根據產品id的不一樣而不一樣,因此咱們能夠經過request.method == 'GET' 來判斷當前訪問提交的是GET方式,並且訪問的路徑是/api/product/時,咱們就不作權限判斷處理。
點擊main.py運行debug,而後在瀏覽器上輸入:http://127.0.0.1:81/api/about/ 就能夠看到已經能夠取到數據了
打開index.html頁面代碼,將公司介紹那部分html代碼刪掉,替換成下面加上id標籤的代碼
<img id="about_img" width="600" height="150"> <br><br> <span id="about"></span>
而後咱們在底部javascript腳本中添加下面ajax代碼,就能夠看到展現效果了
//讀取服務器記錄
$.ajax({
url: "/api/about/",
type: "GET",
dataType: 'json',
success: function (data) {
$("#about_img").attr('src', data.data.front_cover_img);
$("#about").text(data.data.content);
}
});
產品中心這裏須要顯示四個產品,因此咱們先登陸後臺管理系統,在產品中心那裏能夠先錄入好產品,以下圖
而後打開index.html,找到顯示產品的html代碼,將它們所有刪除,替換成下面內容,用來接收到服務器端記錄之後,替換成對應的html
<div class="panel-body" style="height:460px" id="productsDiv"></div>
將代碼拉到底部,在javascript中,添加下面代碼,它會讀取到產品信息之後,對html內容從新進行組合
$.ajax({ url: "/api/product/?rows=4&page=1", type: "GET", dataType: 'json', success: function (data) { if (data.rows != null && data.rows.length > 0) { for (var i in data.rows) { if (i == 4){ break; } var item = data.rows[i]; var html = ' <div style="float:left; padding-right:6px; padding-bottom:10px"><a href="/product_details.html?id=' + item.id + '"><div><img style="width:290px; height:200px" src=' + item.front_cover_img + ' alt="..." class="thumbnail"></div><div class="text-c" style="padding-top:5px;"><strong>' + item.name + '</strong></div></a></div>' $("#productsDiv").append(html); } } } });
因爲先後臺合用一個接口,前臺接口調用的產口列表是啓用狀態的,不顯示禁用狀態的,然後臺須要獲取全部產品,因此咱們要對接口數據處理一下才行,在接口添加一個參數進行判斷處理,是不是後臺獲取數據,前臺默認返回啓用狀態數據
在product.py中找到接口@get('/api/product/'),添加下面處理
# 判斷是不是前臺提交獲取數據 if type != 'backstage': # 判斷是否已經存在查詢條件了,是的話在原查詢條件後面拼接 if wheres: wheres = wheres + ' and is_enable=1' else: wheres = 'where is_enable=1'
在後臺產品中心頁面的html中,訪問/api/product/接口時,也添加上這個參數,你們在products_list.html頁面中查找/api/product/,將它改成:/api/product/?type=backstage 或 /api/product/?type=backstage&product_class_id=
這樣再刷新首頁,就會出現下面效果了:
關於咱們頁面和聯繫咱們頁面比較簡單,只須要將頁面中間顯示的內容刪除,替換成<span id="content"></span>
在頁面底部的javascript中添加下面代碼,效果就能夠直接看到了。注:聯繫咱們頁面只須要將/api/about/替換成/api/contact_us/就能夠了
$.ajax({ url: "/api/about/", type: "GET", dataType: 'json', success: function (data) { $("#content").html(data.data.content); } });
效果圖:
打開產品中心products.html頁面,這個頁面有兩個位置須要從服務器端讀取數據的,一是分類列表,一是產品列表,須要寫兩個ajax。另外,用戶從菜單欄或首頁進來時,有可能沒有帶分類id,因此在寫js時,須要進行專門的處理,沒有id的,須要從分類列表的ajax中獲取一個id,用做產品列表查詢,具體你們直接看javascript代碼就知道了
首先將分類列表項刪除,替換成<ol class="linenums" id="product_class"></ol>,將產品列表所有html代碼刪除,替換成<div class="panel-body" id="products"></div>
在頁面底部的javascript中添加下面代碼,效果就能夠直接看到了。
因爲先後臺合用一個接口,須要和產品列表接口作樣的處理,區分先後臺獲取數據
var id = getQueryString('id'); if (id != ''){ get_product_list(id); } $.ajax({ url: "/api/product_class/", type: "GET", dataType: 'json', success: function (data) { if (data.rows != null && data.rows.length > 0) { for (var i in data.rows) { var item = data.rows[i]; if (id == '') { id = item.id; get_product_list(id); } var html = ' <li><a href="/products.html?id=' + item.id + '">' + item.name + '</a></li>'; $("#product_class").append(html); } } } }); function get_product_list(id) { $.ajax({ url: "/api/product/?product_class_id=" + id, type: "GET", dataType: 'json', success: function (data) { if (data.rows != null && data.rows.length > 0) { for (var i in data.rows) { var item = data.rows[i]; var html = '<div style="float:left; padding-right:20px; padding-bottom:20px"><a href="/product_details.html?id=' + item.id + '"><div><img style="width:290px; height:200px" src="' + item.front_cover_img + '" alt="' + item.name + '" class="thumbnail"></div><div class="text-c" style="padding-top:5px;"><strong>' + item.name + '</strong></div></a></div>' $("#products").append(html); } } } }); } /*獲取url中的參數*/ function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return r[2]; return ''; }
咱們打開產品詳情頁面product_details.html,從這個頁面的原型就能夠看到,它也有兩個地方須要與服務器接口交互,一個是產品分類列表,這個同產品中心的代碼同樣,複製過來就能夠了。另外一個是產品信息的展現,須要經過ajax從服務器端獲取指定的產品信息,而後再寫入到頁面中。
咱們能夠先在後臺編輯好一個產品內容,以下圖
將分類列表項刪除,替換成<ol class="linenums" id="product_class"></ol>,爲產品圖片加上id:<img style="width:400px; height:300px" src="" alt="..." class="thumbnail" id="front_cover_img">
刪除產品信息展現內容,替換成:<div style="float:left; font-size: 16px" id="product_info"></div>
刪除產品描述替換成:<div class="panel-body" id="content"></div>
在頁面底部的javascript中添加下面代碼,效果就能夠直接看到了。
$.ajax({ url: "/api/product_class/", type: "GET", dataType: 'json', success: function (data) { if (data.rows != null && data.rows.length > 0) { for (var i in data.rows) { var item = data.rows[i]; var html = ' <li><a href="/products.html?id=' + item.id + '">' + item.name + '</a></li>'; $("#product_class").append(html); } } } }); var id = getQueryString('id'); if (id != '') { $.ajax({ url: "/api/product/" + id + "/", type: "GET", dataType: 'json', success: function (data) { if (data.state == 0) { $("#front_cover_img").attr('src', data.data.front_cover_img); var html = '產品名稱:' + data.data.name + '<br><br>產品編號:' + data.data.code + '<br><br>產品規格:' + data.data.standard + '<br><br>保 質 期:' + data.data.quality_guarantee_period + '<br><br>產 地:' + data.data.place_of_origin + '<br><br>'; $("#product_info").append(html); $("#content").append(data.data.content); } } }); } /*獲取url中的參數*/ function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return r[2]; return ''; } </script>
到此,咱們整個代碼部分就所有完成了,接下來要作的就是服務器的部署工做了
本文對應的源碼下載(完整代碼)
版權聲明:本文原創發表於 博客園,做者爲 AllEmpty 本文歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然視爲侵權。
python開發QQ羣:669058475(本羣已滿)、733466321(能夠加2羣) 做者博客:http://www.cnblogs.com/EmptyFS/