Django商城專案筆記No.16使用者部分-使用者中心收貨地址
阿新 • • 發佈:2018-11-10
首先完成省市區三級聯動
新建areas應用
python ../../manage.py startapp areas
模型類程式碼
class Area(models.Model): """ 行政區劃 """ name = models.CharField(max_length=20, verbose_name='名稱') parent = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='subs', null=True, blank=True, verbose_name='上級行政區劃') class Meta: db_table = 'tb_areas' verbose_name = '行政區劃' verbose_name_plural = '行政區劃' def __str__(self): return self.name
模型類程式碼說明:
parent = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='subs', null=True, blank=True, verbose_name='上級行政區劃
self:自關聯
on_delete=models.SET_NULL 在刪除父級的時候,自己的parent_id設定為空,這裡就不在級聯刪除了,避免誤刪除,採集資料不容易。
related_name=’subs’ 這個跟flask的backref很類似。 意思為如果想找自己的子級,就可以通過area.subs找到自己下級所有的area區域。
之後配置應用
然後遷移資料庫
python manage.py makemigrations
python manage.py migrate
匯入測試資料指令碼
增加執行許可權
返回省市區資料的後端檢視集實現
定義檢視最終如下
採用檢視集
序列化器
定義路由
DRF快取的實現
省市區的資料是經常被使用者查詢使用的,而且資料基本不變化,所以我們可以將省市區資料進行快取處理,減少資料庫的查詢次數。
在Django REST framework中使用快取,可以通過drf-extensions
擴充套件來實現。
關於擴充套件使用快取的文件,可參考連結http://chibisov.github.io/drf-extensions/docs/#caching
安裝
pip install drf-extensions
使用方法
配置檔案
禁止分頁
前端程式碼
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>美多商城-使用者中心</title> <link rel="stylesheet" type="text/css" href="css/reset.css"> <link rel="stylesheet" type="text/css" href="css/main.css"> <script type="text/javascript" src="js/host.js"></script> <script type="text/javascript" src="js/vue-2.5.16.js"></script> <script type="text/javascript" src="js/axios-0.18.0.min.js"></script> <script> var user_id = sessionStorage.user_id || localStorage.user_id; var token = sessionStorage.token || localStorage.token; if (!(user_id && token)) { location.href = '/login.html?next=/user_center_site.html'; } </script> </head> <body> <div id="app" v-cloak> <div class="header_con"> <div class="header"> <div class="welcome fl">歡迎來到美多商城!</div> <div class="fr"> <div class="login_btn fl"> 歡迎您:<em>{{ username }}</em> <span>|</span> <a @click="logout">退出</a> </div> <div class="user_link fl"> <span>|</span> <a href="user_center_info.html">使用者中心</a> <span>|</span> <a href="cart.html">我的購物車</a> <span>|</span> <a href="user_center_order.html">我的訂單</a> </div> </div> </div> </div> <div class="search_bar clearfix"> <a href="index.html" class="logo fl"><img src="images/logo.png"></a> <div class="sub_page_name fl">| 使用者中心</div> <form method="get" action="/search.html" class="search_con fr mt40"> <input type="text" class="input_text fl" name="q" placeholder="搜尋商品"> <input type="submit" class="input_btn fr" name="" value="搜尋"> </form> </div> <div class="main_con clearfix"> <div class="left_menu_con clearfix"> <h3>使用者中心</h3> <ul> <li><a href="user_center_info.html">· 個人資訊</a></li> <li><a href="user_center_order.html">· 全部訂單</a></li> <li><a href="user_center_site.html" class="active">· 收貨地址</a></li> <li><a href="user_center_pass.html">· 修改密碼</a></li> </ul> </div> <div class="right_content clearfix"> <div class="site_top_con"> <a @click="show_add">新增收貨地址</a> <span>您已建立了<b>{{addresses.length}}</b>個收貨地址,最多可建立<b>{{ limit }}</b>個</span> </div> <div class="site_con" v-for="(address, index) in addresses"> <div class="site_title"> <div v-if="is_set_title[index]"> <input v-model="input_title" type="text" name=""> <input @click="save_title(index)" type="button" name="" value="保 存"> <input @click="cancel_title(index)" type="reset" name="" value="取 消"> </div> <div v-else> <h3>{{ address.title }}</h3> <a @click="show_edit_title(index)"></a> </div> <em v-if="address.id==default_address_id">預設地址</em> <span @click="del_address(index)">×</span> </div> <ul class="site_list"> <li><span>收貨人:</span><b>{{ address.receiver }}</b></li> <li><span>所在地區:</span><b>{{ address.province }} {{address.city}} {{ address.district }}</b></li> <li><span>地址:</span><b>{{ address.place }}</b></li> <li><span>手機:</span><b>{{ address.mobile }}</b></li> <li><span>固定電話:</span><b>{{ address.tel }}</b></li> <li><span>電子郵箱:</span><b>{{ address.email }}</b></li> </ul> <div class="down_btn"> <a v-if="address.id!=default_address_id" @click="set_default(index)">設為預設</a> <a @click="show_edit(index)">編輯</a> </div> </div> </div> </div> <div class="footer"> <div class="foot_link"> <a href="#">關於我們</a> <span>|</span> <a href="#">聯絡我們</a> <span>|</span> <a href="#">招聘人才</a> <span>|</span> <a href="#">友情連結</a> </div> <p>CopyRight © 2016 北京美多商業股份有限公司 All Rights Reserved</p> <p>電話:010-****888 京ICP備*******8號</p> </div> <div class="pop_con" v-show="is_show_edit"> <div class="site_con site_pop"> <div class="site_pop_title"> <h3 v-if="editing_address_index">編輯收貨地址</h3> <h3 v-else>新增收貨地址</h3> <a @click="is_show_edit=false">×</a> </div> <form> <div class="form_group"> <label>*收貨人:</label> <input v-model="form_address.receiver" @blur="check_receiver" type="text" name=""> <span v-show="error_receiver" class="error_tip">請填寫收件人</span> </div> <div class="form_group"> <label>*所在地區:</label> <select v-model="form_address.province_id"> <option v-for="province in provinces" v-bind:value="province.id">{{ province.name }}</option> </select> <select v-model="form_address.city_id"> <option v-for="city in cities" v-bind:value="city.id">{{ city.name }}</option> </select> <select v-model="form_address.district_id"> <option v-for="district in districts" v-bind:value="district.id">{{ district.name }}</option> </select> </div> <div class="form_group"> <label>*詳細地址:</label> <input v-model="form_address.place" @blur="check_place" type="text" name=""> <span v-show="error_place" class="error_tip">請填寫地址資訊</span> </div> <div class="form_group"> <label>*手機:</label> <input v-model="form_address.mobile" @blur="check_mobile" type="text" name=""> <span v-show="error_mobile" class="error_tip">手機資訊有誤</span> </div> <div class="form_group"> <label>固定電話:</label> <input v-model="form_address.tel" type="text" name=""> </div> <div class="form_group"> <label>郵箱:</label> <input v-model="form_address.email" @blur="check_email" type="text" name=""> <span v-show="error_email" class="error_tip">郵箱資訊有誤</span> </div> <input @click="save_address" type="button" name="" value="保 存" class="info_submit"> <input @click="is_show_edit=false" type="reset" name="" value="取 消" class="info_submit info_reset"> </form> </div> <div class="mask"></div> </div> </div> <script type="text/javascript" src="js/user_center_site.js"></script> </body> </html>View Code
js程式碼
var vm = new Vue({ el: '#app', data: { host: host, user_id: sessionStorage.user_id || localStorage.user_id, token: sessionStorage.token || localStorage.token, username: sessionStorage.username || localStorage.username, is_show_edit: false, provinces: [], cities: [], districts: [], addresses: [], limit: '', default_address_id: '', form_address: { receiver: '', province_id: '', city_id: '', district_id: '', place: '', mobile: '', tel: '', email: '', }, error_receiver: false, error_place: false, error_mobile: false, error_email: false, editing_address_index: '', // 正在編輯的地址在addresses中的下標,''表示新增地址 is_set_title: [], input_title: '' }, mounted: function(){ axios.get(this.host + '/areas/', { responseType: 'json' }) .then(response => { this.provinces = response.data; }) .catch(error => { alert(error.response.data); }); }, watch: { 'form_address.province_id': function(){ if (this.form_address.province_id) { axios.get(this.host + '/areas/'+ this.form_address.province_id + '/', { responseType: 'json' }) .then(response => { this.cities = response.data.subs; }) .catch(error => { console.log(error.response.data); this.cities = []; }); } }, 'form_address.city_id': function(){ if (this.form_address.city_id){ axios.get(this.host + '/areas/'+ this.form_address.city_id + '/', { responseType: 'json' }) .then(response => { this.districts = response.data.subs; }) .catch(error => { console.log(error.response.data); this.districts = []; }); } } }, methods: { // 退出 logout: function(){ sessionStorage.clear(); localStorage.clear(); location.href = '/login.html'; }, clear_all_errors: function(){ this.error_receiver = false; this.error_mobile = false; this.error_place = false; this.error_email = false; }, // 展示新增地址介面 show_add: function(){ this.clear_all_errors(); this.editing_address_index = ''; this.form_address.receiver = ''; this.form_address.province_id = ''; this.form_address.city_id = ''; this.form_address.district_id = ''; this.form_address.place = ''; this.form_address.mobile = ''; this.form_address.tel = ''; this.form_address.email = ''; this.is_show_edit = true; }, // 展示編輯地址介面 show_edit: function(index){ this.clear_all_errors(); this.editing_address_index = index; // 只獲取資料,防止修改form_address影響到addresses資料 this.form_address = JSON.parse(JSON.stringify(this.addresses[index])); this.is_show_edit = true; }, check_receiver: function(){ if (!this.form_address.receiver) { this.error_receiver = true; } else { this.error_receiver = false; } }, check_place: function(){ if (!this.form_address.place) { this.error_place = true; } else { this.error_place = false; } }, check_mobile: function(){ var re = /^1[345789]\d{9}$/; if(re.test(this.form_address.mobile)) { this.error_mobile = false; } else { this.error_mobile = true; } }, check_email: function(){ if (this.form_address.email) { var re = /^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$/; if(re.test(this.form_address.email)) { this.error_email = false; } else { this.error_email = true; } } }, // 儲存地址 save_address: function(){ }, // 刪除地址 del_address: function(index){ }, // 設定預設地址 set_default: function(index){ }, // 展示編輯標題 show_edit_title: function(index){ } , // 儲存地址標題 save_title: function(index){ }, // 取消儲存地址 cancel_title: function(index){ } } })View Code
測試