我的第一个python web开发框架(18)——前台页面与接口整合
由于我们前后台系统没有分开,所以前台页面调用接口时,可以直接使用后台管理系统已经完成的接口,不过后台管理系统接口的访问加上了登录验证,所以需要将前台要用到的接口进行处理,让它们设置到白名单当中
我们打开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)——前台页面与接口整合的更多相关文章
- 我的第一个python web开发框架(39)——后台接口权限访问控制处理
前面的菜单.部门.职位与管理员管理功能完成后,接下来要处理的是将它们关联起来,根据职位管理中选定的权限控制菜单显示以及页面数据的访问和操作. 那么要怎么改造呢?我们可以通过用户的操作步骤来一步步进行处 ...
- 我的第一个python web开发框架(41)——总结
我的第一个python web开发框架系列博文从17年6.7月份开始写(存了近十章稿留到9月份才开始发布),到今天结束,一年多时间,想想真不容易啊. 整个过程断断续续,中间有段时间由于工作繁忙停了好长 ...
- 我的第一个python web开发框架(14)——后台管理系统登录功能
接下来正式进入网站的功能开发.要完成后台管理系统登录功能,通过查看登录页面,我们可以了解到,我们需要编写验证码图片获取接口和登录处理接口,然后在登录页面的HTML上编写AJAX. 在进行接口开发之前, ...
- 我的第一个python web开发框架(1)——前言
由于之前经验不是很丰富,写的C#系统太过复杂,所以一直想重写,但学的越多越觉得自己懂的越少,越觉的底气不足.所以一直不敢动手,在内心深处对自己讲,要静下心来认真学习,继续沉淀沉淀.这两年多以来找各种机 ...
- 我的第一个python web开发框架(3)——怎么开始?
小白与小美公司经过几次接触商谈,好不容易将外包签订了下来,准备开始大干一场.不过小白由于没有太多的项目经验,学过python懂得python的基本语法,在公司跟着大家做过简单功能,另外还会一些HTML ...
- 我的第一个python web开发框架(22)——一个安全小事故
在周末的一个早上,小白还在做着美梦,就收到了小美的连环追魂call,电话一直响个不停. 小白打着哈欠拿起电话:早上好美女. 小美:出事了出事了,我们公司网站一早访问是一片空白,什么内容都没有了,你赶急 ...
- 我的第一个python web开发框架(5)——开发前准备工作(了解编码前需要知道的一些常识)
中午吃饭时间到了,小白赶紧向老菜坐的位置走过去. 小白:老大,中午请你吃饭. 老菜:哈哈...又遇到问题了吧,这次得狠狠宰你一顿才行. 小白:行行行,只要您赏脸,米饭任吃,嘻嘻,我们边走边聊. ... ...
- 我的第一个python web开发框架(17)——产品管理
这是后台管理系统最后一个功能,产品管理,它的接口与页面功能与上一章差不多. 获取产品列表接口 @get('/api/product/') def callback(): ""&qu ...
- 我的第一个python web开发框架(40)——后台日志与异常处理
后台权限和底层框架的改造终于完成了,小白也终于可以放下紧悬着的心,可以轻松一下了.这不他为了感谢老菜,又找老菜聊了起来. 小白:多谢老大的帮忙,系统终于改造完成了,可以好好放松一下了. 老菜:呵呵,对 ...
随机推荐
- The Balance
The Balance Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- MapReduce简单分析
在Map端 数据从Map中写入环形缓冲区,进行分区,分区时达到80%后溢出写入到磁盘,这几步同步进行 中间有个Shuffle过程 Reduce端 执行完Map 后到Reduce内存中,进行sort和m ...
- IIC接口下的24C02 驱动分析
本节来学习IIC接口下的24C02 驱动分析,本节学完后,再来学习Linux下如何使用IIC操作24C02 1.I2C通信介绍 它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据,是一个多 ...
- HTML5新特性之WebRTC[转]
原文:http://www.cnblogs.com/jscode/p/3601648.html?comefrom=http://blogread.cn/news/ 1.概述 WebRTC是“网络实时通 ...
- Problem B: 点之间的距离
#include <iostream> #include <vector> #include <cmath> #include <algorithm> ...
- word中表格第一列序号的设置
表格中序号问题 1.新建一个表格.第一列选择编号后,编号后有tab,如下图 2.选中表格的编号,点击新建列表样式, 3.将编号后的字符改成nothing,在将单元格改成居中即可 4.在将单元格改成居中 ...
- ios -Unity3D的EasyAR集成到已经有项目中。
近期 在做AR这一块,用EasyAR集成到iOS端,由于现在到项目已经上线,下一版本要做一个AR功能,于是迫于需求需要,自己研究和翻阅读好多集成到资料. 通过整理分出几个重要到模块,其中在这里指出Xc ...
- [转载] Redis系统性介绍
转载自http://blog.nosqlfan.com/html/3139.html?ref=rediszt 虽然Redis已经很火了,相信还是有很多同学对Redis只是有所听闻或者了解并不全面,下面 ...
- 基于 Vue.js 之 iView UI 框架非工程化实践记要
像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引用一下,不需要就删除.故观念使然,尽管 Nuget 和 Maven ...
- Intrumentation类:ActivityInstrumentationTestCase2学习(1)
public abstract class ActivityInstrumentationTestCase2 extends ActivityTestCase//继承自ActivityTestCase ...