Django框架(九)--動靜分離,api接口,Vue框架

繼承父模板修改頁面

製作goods_list商品列表

電商項目

持續更新

一、動靜分離

視圖

# 提供數據的api接口
# 返回的是一個json對象
def goods_list_api(request,status,page=1):
    if status == '0':    # 下架商品
        goods = Goods.objects.filter(goods_status=0).order_by('goods_number')
    else:    # 在售商品
        goods = Goods.objects.filter(goods_status=1).order_by('goods_number')
    paginator = Paginator(goods,10)
    page_obj = paginator.page(int(page))

    res=[]
    for one in page_obj:
        res.append({
            'goods_number':one.goods_number,
            'goods_name':one.goods_name,
            'goods_price':one.goods_price,
            'goods_count':one.goods_count,
            'goods_location':one.goods_location,
            'goods_safe_date':one.goods_safe_date,
            'goods_status':one.goods_status,
            'goods_pro_time':one.goods_pro_time,
        })
    result = {
        'data':res,
        'page_range':paginator.page_range
    }
    return JsonResponse(result)

報錯:
在這裏插入圖片描述

解決:修改視圖
在這裏插入圖片描述

路由

在這裏插入圖片描述

結果

在這裏插入圖片描述
在這裏插入圖片描述

動態數據渲染

從提供數據的api接口中,提取數據,渲染到頁面上

需要在html頁面中增加一個請求(請求api接口地址):ajax

視圖

增加一個api_goods_list視圖,負責提供頁面

def api_goods_list(request):
    return render(request,'api_goods_list.html')

路由

在這裏插入圖片描述

模板

api_goods_list.html頁面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>api接口提供數據</title>
  <script src="/static/vendor/jquery/jquery.min.js"></script>
</head>
<body>
<div id="content"></div>
  <script>
    $.ajax(
        {
            url:'/goods_list_api/1/1/',
            type:'get',
            data:'',
            success:function (data) {
                console.log(data['data']);
                var p='';
                for(var one in data['data']){
                    p += '<p>'+data['data'][one]['goods_name']+'</p>';
                    $('#content').html(p);
                    {#p = '<p>'+data['data'][one]['goods_name']+'</p>'#}
                    {#$('#content').append(p)#}
                }
            },
            error:function (error) {
                console.log(error);
            }
        }
    )
  </script>
</body>
</html>

結果

在這裏插入圖片描述

上述方法能夠實現動靜分離,包括頁面和提供數據的api接口

動靜分離的好處:

  1. 能夠讓項目變得更加靈活
  2. 數據被使用的範圍被擴大

二、Vue

上面實現了動靜分離,但比較笨拙,可用Vue實現

Vue是一個框架,MVVM設計模式,主要作用是綁定數據

視圖

def vuedemo(request):
    return render(request,'vuedemo.html')

路由

在這裏插入圖片描述

模板

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8">
  <title>Vue</title>
  <script src="/static/js/vue.min.js"></script>
</head>
<body>
<div id="panel">
  <p>
    內容綁定 {{ name }}
  </p>
  <hr>
</div>
<script>
  var vue = new Vue(
      {
          el:'#panel',
          data:{
              name:'zhangsan',
          }
      }
  )
</script>
</body>
</html>

數據並沒有綁定成功
在這裏插入圖片描述

這是因爲django模板將{{ }}認爲是django的模板語法

需要用{% verbatim %}{% endverbatim %}標籤包起來,使得django模板語法失效
在這裏插入圖片描述

(一)Vue基本使用

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"
      xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8">
  <title>Vue</title>
  <script src="/static/js/vue.min.js"></script>
</head>
<body>
{% verbatim %}
<div id="panel">
  <p>
    內容綁定 {{ name }}
  </p>
  <hr>
  <p v-bind:style="style">
    屬性綁定 style/id/class...皆可
  </p>
  <hr>
  <p v-if="flag">
    判斷綁定
  </p>
  <hr>
  <p v-for="p in lists">
    循環綁定 {{ p }}
  </p>
  <hr>
  <button v-on:click="click">
    事件綁定
  </button>
  <hr>
</div>
{% endverbatim %}
<script>
  var vue = new Vue(
      {
          el:'#panel',
          data:{
              name:'zhangsan',
              style:'color:red',
              flag:1,
              lists:['python','java','php'],
          },
          methods:{
              'click':function () {
                  alert('hello world');
              }
          }
      }
  )
</script>
</body>
</html>

結果

在這裏插入圖片描述

總結

  1. 導包

    <script src="/static/js/vue.min.js"></script>
    
  2. 創建一個實例對象

    var vue = new Vue({
    	
    })
    
  3. 數據的綁定

    {{ name }}

  4. 屬性的綁定

    v-bind:style v-bind:id v-bind:class …

  5. 事件的綁定

    v-on:click = “click”

    後面這個click是一個方法名,需要與methods對象當中方法的key值對應

  6. 控制語句的綁定

    判斷v-if=’’

    循環v-for=‘p in 變量’

(二)Vue+api接口實現動靜分離

綁定數據–靜態數據

創建vue_goods_list.html模板

{% extends 'base.html' %}

{% block title %}
  {% if status == '1' %}
    在售商品列表
  {% else %}
    下架商品列表
  {% endif %}
{% endblock %}

{% block label %}
  {% if status == '1' %}
    在售商品列表
  {% else %}
    下架商品列表
  {% endif %}
{% endblock %}

{% block style %}
  <script src="/static/js/vue.min.js"></script>
  <script src="/static/js/vue-resource.js"></script>
{% endblock %}

{% block content %}
  {% verbatim %}
  <div id="content">
    <table class="table">
      <thead>
        <tr>
          <th>商品編號</th>
          <th>商品名稱</th>
          <th>商品價格</th>
          <th>商品數量</th>
          <th>商品產地</th>
          <th>商品保質期</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="one in goods_list">
          <td>{{ one.goods_number }}</td>
          <td>{{ one.goods_name }}</td>
          <td>{{ one.goods_price }}</td>
          <td>{{ one.goods_count }}</td>
          <td>{{ one.goods_location }}</td>
          <td>{{ one.goods_safe_date }}</td>
          <td>
            <button class="btn btn-primary">修改</button>
            <button class="btn btn-warning">下架</button>
          </td>
        </tr>
      </tbody>
      <tfoot>
      </tfoot>
    </table>
    <ul class="pagination" style="float: right;">
      <li class="paginate_button page-item previous" v-for="page in page_range">
        <a class="page-link" v-bind:href="page">{{ page }}</a>
      </li>
    </ul>
  </div>
  {% endverbatim %}
{% endblock %}

{% block script %}
  <script>
    var vue = new Vue(
        {
            //vue只能進行靜態數據的綁定,這裏構建一些靜態數據
            el:'#content',
            data:{
                goods_list:[
                    {
                        "goods_number": "00001",
                        "goods_name": "山西大白菜",
                        "goods_price": "100",
                        "goods_count": "200",
                        "goods_location": "陝西",
                        "goods_safe_date": "1"
                    },
                    {
                        "goods_number": "00002",
                        "goods_name": "北京大蘿蔔",
                        "goods_price": "100",
                        "goods_count": "100",
                        "goods_location": "東北",
                        "goods_safe_date": "1"
                    },
                    {
                        "goods_number": "00003",
                        "goods_name": "東北粉條",
                        "goods_price": "90",
                        "goods_count": "100",
                        "goods_location": "河北",
                        "goods_safe_date": "1"
                    },
                    {
                        "goods_number": "00004",
                        "goods_name": "河南燴麪",
                        "goods_price": "100",
                        "goods_count": "200",
                        "goods_location": "河南",
                        "goods_safe_date": "1"
                    },
                    {
                        "goods_number": "00005",
                        "goods_name": "蘭州拉麪",
                        "goods_price": "100",
                        "goods_count": "300",
                        "goods_location": "北京",
                        "goods_safe_date": "1"
                    },
                    {
                        "goods_number": "00006",
                        "goods_name": "山東大蔥",
                        "goods_price": "100",
                        "goods_count": "400",
                        "goods_location": "山東",
                        "goods_safe_date": "1"
                    },
                ],
                page_range:[1,2,3,4,5],
            }
        }
    )
  </script>
{% endblock %}

視圖

直接將模板頁面修改爲vue_goods_list.html頁面
在這裏插入圖片描述

綁定數據–動態數據

Vue作用是數據的綁定,但是沒有辦法進行動態數據的綁定,就出現了vue-resource

模板

修改vue_goods_list.html頁面

{% extends 'base.html' %}

{% block title %}
  {% if status == '1' %}
    在售商品列表
  {% else %}
    下架商品列表
  {% endif %}
{% endblock %}

{% block label %}
  {% if status == '1' %}
    在售商品列表
  {% else %}
    下架商品列表
  {% endif %}
{% endblock %}

{% block style %}
  <script src="/static/js/vue.min.js"
          xmlns:v-bind="http://www.w3.org/1999/xhtml"
          xmlns:v-bind="http://www.w3.org/1999/xhtml"
          xmlns:v-bind="http://www.w3.org/1999/xhtml"
          xmlns:v-bind="http://www.w3.org/1999/xhtml"></script>
  <script src="/static/js/vue-resource.js"></script>
{% endblock %}

{% block content %}
  {% verbatim %}
  <div id="content">
    <table class="table">
      <thead>
        <tr>
          <th>商品編號</th>
          <th>商品名稱</th>
          <th>商品價格</th>
          <th>商品數量</th>
          <th>商品產地</th>
          <th>商品保質期</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="one in goods_list">
          <td>{{ one.goods_number }}</td>
          <td>{{ one.goods_name }}</td>
          <td>{{ one.goods_price }}</td>
          <td>{{ one.goods_count }}</td>
          <td>{{ one.goods_location }}</td>
          <td>{{ one.goods_safe_date }}</td>
          <td>
            <button class="btn btn-primary">修改</button>
            <button class="btn btn-warning">下架</button>
          </td>
        </tr>
      </tbody>
      <tfoot>
      </tfoot>
    </table>
    <ul class="pagination" style="float: right;">
      <li class="paginate_button page-item previous" v-for="page in page_range">
        <a class="page-link" v-bind:href="page">{{ page }}</a>
      </li>
    </ul>
  </div>
  {% endverbatim %}
{% endblock %}

{% block script %}
  <script>
    Vue.use(VueResource);    //聲明使用vue_resource
    var vue = new Vue(
        {
            //發送一個get請求,從api接口中獲取數據,渲染到指定頁面
            el:'#content',
            data:{
                goods_list:'',
                page_range:'',
            },
            created:function () {
                url='/goods_list_api/1/1';
                this.$http.get(url).then(
                    //相當於ajax中的success
                    function (data){
                        //console.log(data['data']['data'])
                        console.log(data['data']['page_range']);
                        this.goods_list=data['data']['data'];
                        this.page_range=data['data']['page_range'];
                    },
                    //相當於ajax中的error
                    function (error) {
                        console.log(error)
                    }
                )
            }
        }
    )
  </script>
{% endblock %}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章