由于我们前后台系统没有分开,所以前台页面调用接口时,可以直接使用后台管理系统已经完成的接口,不过后台管理系统接口的访问加上了登录验证,所以需要将前台要用到的接口进行处理,让它们设置到白名单当中

  我们打开main.py文件,在勾子函数中@hook('before_request')中找到下面代码

# 过滤不用做任何操作的路由(即过滤不用进行判断是否登录和记录日志的url)
if path_info in ['/favicon.ico', '/', '/api/verify/']:
return

  这里前面已讲过,是跳过那些需要权限判断和进行日志记录的访问,对于后台上传的图片来说,我们不需要进行日志记录和权限判断,所以在这里添加上日志访问的路由

# 过滤不用做任何操作的路由(即过滤不用进行判断是否登录和记录日志的url)
if path_info in ['/favicon.ico', '/', '/api/verify/'] or path_info.find('/upload/') > -1:
return

  path_info是当前客户端访问的url,通常url是固定的话,我们可以通过in的方式直接进行判断

  因为上传的图片统一存放在/upload/这个目录中,而访问图片的路由是/upload/xxxx/xxxxxxxxx.jpg,每张图片访问路径都不一样,新上传的图片就会生成新的链接,url是动态变化的,所以我们使用查找的方式来进行判断当前url是否是图片,如果是的话,则不执行下面的操作。

  同样在勾子函数@hook('before_request')中找到下面代码

# 过滤不用进行登录权限判断的路由(登录与退出登录不用检查是否已经登录)
url_list = ["/api/login/", "/api/logout/"]
if path_info in url_list:
pass

  为了方便出现问题时及时排查,所以我们会将客户端对接口的访问,以及提交的参数记录到日志中,保存一段时间,所以我们会将一些访问频繁但对分析无关的接口添加到前面过滤处理中。

  因为对后台管理系统操作时,我们需要对用户权限进行验证,所以会在勾子中统一进行验证用户是否已经登录成功。但有一些接口我们是不必要进行验证的,比如登录和退出登录接口,如果它们不排除在外的话,那么用户将无法登录,因为每次访问登录接口都会返回你未登录不能访问,这样就会出现死循环,未登录不能访问接口,而不能访问接口则无法进行登录的怪圈当中,所以我们需要对一些无需登录就可以访问的接口进行例外处理。

  对于前台获取公司介绍、联系我们、产品分类、产品列表和产品信息的接口,我们可以将它们添加到这里来,进行过滤。

# 过滤不用进行登录权限判断的路由(登录与退出登录不用检查是否已经登录)
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,然后进行区分处理。

  我们知道获取产品信息的接口路由是:@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/

我的第一个python web开发框架(18)——前台页面与接口整合的更多相关文章

  1. 我的第一个python web开发框架(39)——后台接口权限访问控制处理

    前面的菜单.部门.职位与管理员管理功能完成后,接下来要处理的是将它们关联起来,根据职位管理中选定的权限控制菜单显示以及页面数据的访问和操作. 那么要怎么改造呢?我们可以通过用户的操作步骤来一步步进行处 ...

  2. 我的第一个python web开发框架(41)——总结

    我的第一个python web开发框架系列博文从17年6.7月份开始写(存了近十章稿留到9月份才开始发布),到今天结束,一年多时间,想想真不容易啊. 整个过程断断续续,中间有段时间由于工作繁忙停了好长 ...

  3. 我的第一个python web开发框架(14)——后台管理系统登录功能

    接下来正式进入网站的功能开发.要完成后台管理系统登录功能,通过查看登录页面,我们可以了解到,我们需要编写验证码图片获取接口和登录处理接口,然后在登录页面的HTML上编写AJAX. 在进行接口开发之前, ...

  4. 我的第一个python web开发框架(1)——前言

    由于之前经验不是很丰富,写的C#系统太过复杂,所以一直想重写,但学的越多越觉得自己懂的越少,越觉的底气不足.所以一直不敢动手,在内心深处对自己讲,要静下心来认真学习,继续沉淀沉淀.这两年多以来找各种机 ...

  5. 我的第一个python web开发框架(3)——怎么开始?

    小白与小美公司经过几次接触商谈,好不容易将外包签订了下来,准备开始大干一场.不过小白由于没有太多的项目经验,学过python懂得python的基本语法,在公司跟着大家做过简单功能,另外还会一些HTML ...

  6. 我的第一个python web开发框架(22)——一个安全小事故

    在周末的一个早上,小白还在做着美梦,就收到了小美的连环追魂call,电话一直响个不停. 小白打着哈欠拿起电话:早上好美女. 小美:出事了出事了,我们公司网站一早访问是一片空白,什么内容都没有了,你赶急 ...

  7. 我的第一个python web开发框架(5)——开发前准备工作(了解编码前需要知道的一些常识)

    中午吃饭时间到了,小白赶紧向老菜坐的位置走过去. 小白:老大,中午请你吃饭. 老菜:哈哈...又遇到问题了吧,这次得狠狠宰你一顿才行. 小白:行行行,只要您赏脸,米饭任吃,嘻嘻,我们边走边聊. ... ...

  8. 我的第一个python web开发框架(17)——产品管理

    这是后台管理系统最后一个功能,产品管理,它的接口与页面功能与上一章差不多. 获取产品列表接口 @get('/api/product/') def callback(): ""&qu ...

  9. 我的第一个python web开发框架(40)——后台日志与异常处理

    后台权限和底层框架的改造终于完成了,小白也终于可以放下紧悬着的心,可以轻松一下了.这不他为了感谢老菜,又找老菜聊了起来. 小白:多谢老大的帮忙,系统终于改造完成了,可以好好放松一下了. 老菜:呵呵,对 ...

随机推荐

  1. 关于NIM博弈结论的证明

    关于NIM博弈结论的证明 NIM博弈:有k(k>=1)堆数量不一定的物品(石子或豆粒…)两人轮流取,每次只能从一堆中取若干数量(小于等于这堆物品的数量)的物品,判定胜负的条件就是,最后一次取得人 ...

  2. Handshakes

    Description Last week, n students participated in the annual programming contest of Marjar Universit ...

  3. Redis的各项功能解决了哪些问题?

    先看一下Redis是一个什么东西.官方简介解释到:Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用.同时支持string ...

  4. 解决打开MATLAB时出现“Waring:could not read file classpath.txt”,等问题

    估计刚安装好的matlab是不会出现这个问题的,出现问题肯定是在某一次用360或者电脑管家清理垃圾之后才会出现这个问题. 首先声明我的matlab版本是matlab R2014a,下载链接:(额,网盘 ...

  5. 【转载】目前主流过滤XSS的三种技术

    目前主流过滤XSS的三种技术 过滤 过滤,顾名思义,就是将提交上来的数据中的敏感词汇直接过滤掉.例如对"<script>"."<a>". ...

  6. Flex 基础语法(三)

    2.flex-wrap 默认情况下,项目都排在一条线(又称"轴线")上.flex-wrap属性定义,如果一条轴线排不下,如何换行 属性 含义 nowrap(默认值) 不换行 wra ...

  7. Chrome DevTools 开发者工具 技巧 调试

    https://developers.google.com/chrome-developer-tools/docs/tips-and-tricks   1.console面板多行输入 Shift +  ...

  8. Linux服务器上安装vsftpd

    1.首先判断你服务器上是否安装了vsftpd rpm -q vsftpd   2.安装vsftpd yum -y install vsftpd   3.重启vsftpd service vsftpd ...

  9. 利用C#实现分布式数据库查询

    随着传统的数据库.计算机网络和数字通信技术的飞速发展,以数据分布存储和分布处理为主要特征的分布式数据库系统的研究和开发越来越受到人们的关注.但由于其开发较为复杂,在一定程度上制约了它的发展.基于此,本 ...

  10. EAS(学生管理系统)初建

    一.确定开发使用的技术             本次开发EAS示例网站,使用Servlet+JSP+MySQL技术,其中包括使用bootstrap工具完成简易前端页面设计.所有数据实体与数据关系皆用数 ...