繼承父模板修改頁面
製作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 %}