首页 > 其他 > 详细

Django接口开发

时间:2020-06-22 22:06:39      阅读:62      评论:0      收藏:0      [点我收藏+]

Django接口开发

一、前后端分离

  • 传统开发模式

url -->> 视图函数(逻辑判断、调用数据库、渲染HTML)-->>向浏览器返回HTML页面。
项目后台的商品列表页面已经使用传统开发模式实现了

但是呢,有时候我们需要将这些内容在移动端(手机APP)或者的设备上显示。那怎么办呢?
我们可以再编写一套后台逻辑给移动端使用。但是这样比较麻烦,工作量比较大。有没有更简单的方式呢?我们可以使用前后端分离开发模式

二、前后端分离模型

前后端分离模型指的是后端只负责返回数据,不再负责渲染页面。前端负责渲染数据

接下来就要探讨一下返回的数据类型,如果我们返回Python中的字典或者列表,但是前端人员或者移动端人员不一定会Python语法。我们可以返回一种前端人员、后台人员都会的一种数据类型,这样就可以顺利的完成开发了。一般在开发中我们返回JSON或者XML数据类型

三、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介绍

    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、前端需要做什么?

    • 以何种形式展示:web网页展示
      发送参数
      获取响应
      局部刷新-修改DOM

    2、后端需要做什么?

    • 获取商品类型,根据商品类型查询商品
      get请求
    # 视图
    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>
    
    • v-for 可以通过一个对象的属性来迭代数据
    
    <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>
    
    • 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码
    <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

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

Django接口开发

原文:https://www.cnblogs.com/markshui/p/13179168.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!