继承父模板修改页面
制作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接口
动静分离的好处:
- 能够让项目变得更加灵活
- 数据被使用的范围被扩大
二、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>
结果
总结
-
导包
<script src="/static/js/vue.min.js"></script>
-
创建一个实例对象
var vue = new Vue({ })
-
数据的绑定
{{ name }}
-
属性的绑定
v-bind:style v-bind:id v-bind:class …
-
事件的绑定
v-on:click = “click”
后面这个click是一个方法名,需要与methods对象当中方法的key值对应
-
控制语句的绑定
判断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 %}