url -->> 视图函数(逻辑判断、调用数据库、渲染HTML)-->>向浏览器返回HTML页面。
项目后台的商品列表页面已经使用传统开发模式实现了
但是呢,有时候我们需要将这些内容在移动端(手机APP)或者的设备上显示。那怎么办呢?
我们可以再编写一套后台逻辑给移动端使用。但是这样比较麻烦,工作量比较大。有没有更简单的方式呢?我们可以使用前后端分离开发模式
前后端分离模型指的是后端只负责返回数据,不再负责渲染页面。前端负责渲染数据
接下来就要探讨一下返回的数据类型,如果我们返回Python中的字典或者列表,但是前端人员或者移动端人员不一定会Python语法。我们可以返回一种前端人员、后台人员都会的一种数据类型,这样就可以顺利的完成开发了。一般在开发中我们返回JSON或者XML数据类型
JSON介绍
JSON(JavaScript Object Notation) : 是一种轻量级的数据交换格式,JSON数据格式类似于Python中的字典
XML介绍
XML(Extensible Markup Language): 可扩展标记语言,很少企业使用XML进行数据传输,了解即可
JsonResponse
form django.http import JsonResponse
使用JsonResponse对象可以将Python中的字典或者其他数据类型转换为JSON数据
# 路由
urlpatterns += [
# 查询所有商品
path(‘api/goodses/‘, api_view.select_all_goods),
# 视图
def select_all_goods(request):
"""查询所有的商品"""
# 查询所有商品得到的是QuerySet类型的对象
goods_qs = Goods.objects.all()
# 转成列表字典格式
goods_list = [{"id": goods.id, "name": goods.name} for goods in goods_qs]
# JsonResponse
return JsonResponse(goods_list,safe=False,json_dumps_params= {"ensure_ascii":False})
safe=False可以使用列表,默认只转换字典格式
son_dumps_params={"ensure_ascii":False}:显示中文
AJAX介绍
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步JavaScript和XML”。即使用JavaScript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)还有JSON数据
AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新,这一特点给用户的感受是在不知不觉中完成请求和响应过程
应用场景:注册时信息校验(百度首页注册)
AJAX格式
使用原生的JavaScript 使用AJAX 比较麻烦,我们采用 jQuery 实现 AJAX 请求。
1、语法:$.ajax({参数1:值1,参数2,值2})
参数 | 描述 |
---|---|
url | 发送请求的地址 |
type | 请求方式("POST" 或 "GET"), 默认为 "GET"。注意:其它 HTTP 请求方法如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持 |
data | 发送到服务器的数据。格式 {key:value,key:value} |
error | 请求失败时调用此函数 |
success | 请求成功后的回调函数,参数:由服务器返回数据 |
dataType | 预期服务器返回的数据类型。如果不指定,浏览器会智能判断 |
可用值:
"xml": 返回 XML 文档,可用 jQuery 处理。
"html": 返回纯文本 HTML 信息;
"script": 返回纯文本 JavaScript 代码。
"json": 返回 JSON 数据 |
案例:
1、前端需要做什么?
2、后端需要做什么?
# 视图
def select_all_goods_by_goodstype(request):
"""查看更多,根据商品类型查询所有商品"""
# 接收参数
goodstype_id = request.GET.get("goodstype_id")
# 查询数据
goods_qs = Goods.objects.filter(goodstype_id=goodstype_id)
# 转成列表字典格式
goods_list = [{"id": goods.id, "name": goods.name,"price":goods.price,"picture":goods.picture.name,"unite":goods.unite} for goods in goods_qs]
# JsonResponse
return JsonResponse(goods_list,safe=False,json_dumps_params={"ensure_ascii":False})
# 前端页面
<script>
// 根据url中的goodstype_id
var url = window.location.href;
var goodstype_id = url.split("?")[1].split("=")[1];
//发送请求
$.ajax({
"url": "/api/more/",
"method": "get",
"data": {"goodstype_id": goodstype_id},
"success": function (data) {
{#console.log(data)#}
{#console.log(typeof data)#}
var divs = ""
//遍历
for(var i=0;i<data.length;i++){
var goods = data[i]
var id = goods["id"]
var name = goods["name"]
var picture = goods["picture"]
var price = goods["price"]
var unite = goods["unite"]
divs = divs+‘<div class="col-xs-12 col-sm-3"><a href="detail.html" class="thumbnail"><img src="/static/ft/images/‘+picture+‘" class="img-responsive"></a><p class="text-center">‘+name+‘</p><p class="text-center myps"><span>¥‘+price+‘</span><span>‘+price+‘/‘+unite+‘</span><span><img src="/static/ft/images/carts.png"/></span></p></div>‘
}
//修改dom,这里比较费劲
$("#mybody").html(divs)
},
"error": function () {
alert("error")
}
})
$.ajax({
"url": "/api/goodstype/",
"method": "get",
"data": {"goodstype_id": goodstype_id},
"success": function (data) {
$("#goodstype").html("全部分类 > "+data["name"])
},
"error": function () {
alert("error")
}
})
</script>
我们可以使用JS中的text、innerHtml、append 等方法,但是比较麻烦,我们可以使用Vue框架中的语法
Vue介绍
Vue 是一套用于构建用户界面的JavaScript框架,前端使用Vue的目的就是把AJAX里面的数据绑定到前端
Vue基本语法
下载引入
1、第一个应用
在Django的模版中使用Vue时,语法冲突,需要增加标签verbatim处理
Vue.js的应用可以分为2个重要的组成部分,一个是视图(也就是HTML代码)另外一个是脚本
# Vue使用[[]]语法
"delimiters":["[[","]]"]
2、v-bind 常用于绑定属性
<a v-bind:href="url">百度</a>
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true值的时候被渲染
<div id="app">
<div v-if="type === ‘A‘">
A
</div>
<div v-else-if="type === ‘B‘">
B
</div>
<div v-else-if="type === ‘C‘">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
<script>
new Vue({
el: ‘#app‘,
data: {
type: ‘C‘
}
})
</script>
<div id="app">
<ul>
<li v-for="value in object">
{{ value }}
</li>
</ul>
</div>
<script>
new Vue({
el: ‘#app‘,
data: {
object: {
name: ‘菜鸟教程‘,
url: ‘http://www.runoob.com‘,
slogan: ‘学的不仅是技术,更是梦想!‘
}
}
})
</script>
<div id="app">
<button v-on:click="counter += 1">增加 1</button>
<p>这个按钮被点击了 {{ counter }} 次。</p>
</div>
<script>
new Vue({
el: ‘#app‘,
data: {
counter: 0
}
})
</script>
Vue异步请求
<div id="box">
<input type="button" @click="get()" value="点我异步获取数据(Get)">
</div>
<script type = "text/javascript">
window.onload = function(){
var vm = new Vue({
el:‘#box‘,
data:{
msg:‘Hello World!‘,
},
methods:{
get:function(){
//发送get请求
this.$http.get(‘/try/ajax/ajax_info.txt‘).then(function(res){
document.write(res.body);
},function(){
console.log(‘请求失败处理‘);
});
}
}
});
}
</script>
案例:商品中 查看更多 功能
1、导入包
2、使用Vue,搭建环境
<script>
// 根据url中的goodstype_id
var url = window.location.href;
var goodstype_id = url.split("?")[1].split("=")[1];
//创建VUE对象
new Vue({
el: "#mybody",
delimiters: ["[[", "]]"],
data: {
goods_list: [],
},
methods: {
select_info: function () {
this.$http.get("/api/more/?goodstype_id="+goodstype_id).then(function (content) {
//console.log(content)
//console.log(content.data)
this.goods_list = content.data
},function (data) {
alert("error")
})
}
},
mounted:function () {//相当于js onload表示窗体加载完毕
this.select_info()
}
})
</script>
3、使用Vue绑定
<div class="panel-body" id="mybody">
<div class="col-xs-12 col-sm-3" v-for="goods in goods_list">
<a href="detail.html" class="thumbnail">
<img v-bind:src="‘/static/ft/images/‘+[[goods.picture]]" class="img-responsive">
</a>
<p class="text-center">[[goods.name]]</p>
<p class="text-center myps"><span>¥[[goods.price]]</span><span>[[goods.price]]/[[goods.unite]]</span><span><img
src="/static/ft/images/carts.png"/></span></p>
</div>
</div>
REST(Representational State Transfer的简称,中文翻译为“表现层状态转移”)与技术无关,
是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。基于这个风格
设计的软件可以更简洁,更有层次,更易于实现缓存等机制
满足这些约束条件和原则的应用程序或设计就是 RESTful
REST需要遵循如下10条规则:
1、协议
API与用户的通信协议,总是使用HTTPS协议
2、域名
在域名上进行区分,例如
子域名方式:
www.ujiuye.com 所有人都知道这是访问网站
api.ujiuye.com(cts.ujiuye.com) 看到这个网站就就知道返回json、xml数据
Url上区分:
www.ujiuye.com/
www.ujiuye.com/api/ (添加一个api 目录,让人一看到就知道是一个接口)
3、版本
因为项目存在着版本迭代更新,因此建议在url上添加版本
www.ujiuye.com/api/v1/
http://www.example.com/app/1.0/foo
v1、1.0: 就是代表第一版
4、路径
网络上任何东西都是资源,均使用名词表示(可复数)
通俗来说,URL不应该使用动作来描述。例如,下面是一些不符合统一接口 要求的URI:
GET:/getUser/1、 POST:/createUser、PUT:/updateUser/1 、DELETE:/deleteUser/1
建议使用 /user/1
5、HTTP动词
对于资源的具体操作类型,由HTTP动词表示
常用的HTTP动词有下面四个(括号里是对应的SQL命令)
GET(SELECT):从服务器取出资源(一项或多项)
POST(CREATE):在服务器新建一个资源
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
DELETE(DELETE):从服务器删除资源
还有三个不常用的HTTP动词
PATCH(UPDATE):在服务器更新(更新)资源(客户端提供改变的属性)
HEAD:获取资源的元数据
OPTIONS:获取信息,关于资源的哪些属性是客户端可以访问改变的
下面是一些例子
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园(上传文件)
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID:删除某个动物园
GET /zoos/ID/animals:列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
6、过滤信息
如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
下面是一些常见的参数
?limit=10:指定返回记录的数量
?offset=10:指定返回记录的开始位置
?page=2&per_page=100:指定第几页,以及每页的记录数
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
?animal_type_id=1:指定筛选条件
参数的设计允许存在冗余,即允许API路径和URL参数偶尔有重复 比如:
GET /zoos/ID/animals
GET /animals?zoo_id=ID
二者含义是相同的
7、状态码
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
200 OK - [GET]:服务器成功返回用户请求的数据
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - []:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作
401 Unauthorized - []:表示用户没有权限(令牌、用户名、密码错误)
403 Forbidden - [] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - []:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功
8、错误处理
如果状态码是4xx,服务器就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。
{error: "Invalid API key"}
9、返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
10、超媒体
RESTful API最好做到Hypermedia(即返回结果中提供链接,连向其他API方法),使得用户不查文档,也知道下一步应该做什么
比如,Github的API就是这种设计,访问api.github.com会得到一个所有可用API的网址列表
{
"current_user_url": "https://api.github.com/user",
"authorizations_url": "https://api.github.com/authorizations",
// ...
}
从上面可以看到,如果想获取当前用户的信息,应该去访问api.github.com/user,然后就得到了下面结果
{
"message": "Requires authentication",
"documentation_url": "https://developer.github.com/v3"
}
上面代码表示,服务器给出了提示信息,以及文档的网址
11、其他
服务器返回的数据格式,应该尽量使用JSON,避免使用XML
原文:https://www.cnblogs.com/markshui/p/13179168.html