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 %}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章