????前面寫了一篇用JavaScript實現省市縣動態三級聯動的文章:
????《用JavaScript實現動態省市縣三級聯動》http://xpleaf.blog.51cto.com/9315560/1716190
????但是里面實現的方法都是在一個頁面內的,即省市縣的數據都保存在一個html頁面中,數據的請求也是在本頁面內的,這樣的話靈活性不大,我們的需求是,希望把數據保存在服務器,然后在用戶每次點擊時都可以向服務器請求數據,即需要實現類似下面的邏輯功能:
用戶點擊-->onchange觸發事件-->向服務器請求數據-->服務器返回數據-->向當前頁面添加數據
????下面就用Python的Django來實現這個功能。
(PS:有關Django平臺如何部署和搭建,這里就不多說了,大家可以看看《Django Book》,我之前在網上找過很多資料,網友寫的或是一些其他書籍,都沒有《Django Book》講得細致和透徹,所以是強烈推薦!)
1.平臺環境
????操作系統:Windows 7 64位
????開發環境:Eclipse PyDev
2.文件夾結構
????直接看下面的圖片:
????目前很多文件還用不上,在創建Django的項目時或app時,很多文件都是自動生成的,下面會說一說可以用得上的文件。
3.主要功能文件與代碼
(1)MapPro/settings.py
????目前主要是用來設置statics和templates,告訴Django這兩個目錄的存在路徑,添加的代碼如下:
TEMPLATE_DIRS?=?(os.path.join(BASE_DIR,'templates'),)STATICFILES_DIRS?=?(os.path.join(BASE_DIR,'statics'),)
(2)MapPro/urls.py
????設置url路徑和views視圖函數的映射關系,全部代碼如下:
from?django.conf.urls?import?patterns,?include,?url
from?django.contrib?import?admin
from?app01?import?viewsurlpatterns?=?patterns('',#?Examples:#?url(r'^$',?'MapPro.views.home',?name='home'),#?url(r'^blog/',?include('blog.urls')),url(r'^admin/',?include(admin.site.urls)),url(r'^map/$',views.Map),(r'^GetCityData/$',views.Return_City_Data),(r'^GetCountryData/$',views.Return_Country_Data),
)
(3)app01/views.py
????視圖函數文件,用來處理業務邏輯,全部代碼如下:
from?django.shortcuts?import?render,render_to_response
from?django.http?import?HttpResponse
from?django.core.context_processors?import?request
import?json#?Create?your?views?here.def?Map(request):return?render_to_response("map.html")#return?HttpResponse("Hello!")Place_dict?=?{"GuangDong":{"GuangZhou":["PanYu","HuangPu","TianHe"],"QingYuan":["QingCheng","YingDe","LianShan"],"FoShan":["NanHai","ShunDe","SanShui"]},"ShanDong":{"JiNan":["LiXia","ShiZhong","TianQiao"],"QingDao":["ShiNan","HuangDao","JiaoZhou"]},"HuNan":{"ChangSha":["KaiFu","YuHua","WangCheng"],"ChenZhou":["BeiHu","SuXian","YongXian"]}};
def?Return_City_Data(request):province?=?request.GET['Province']print?provinceCity_list?=?[]for?city?in?Place_dict[province]:City_list.append(city)return?HttpResponse(json.dumps(City_list))????def?Return_Country_Data(request):province,city?=?request.GET['Province'],request.GET['City']print?province,cityCountry_list?=?Place_dict[province][city]return?HttpResponse(json.dumps(Country_list))
????這里的代碼比較簡單,就不寫注釋了。
(4)templates/map.html
????templates目錄主要用來放置頁面的模板文件,這里我只創建map.html文件,代碼如下:
<!DOCTYPE?html>
<html>
<head?lang="en"><meta?charset="UTF-8"><title>三級聯動測試</title><script?src="/static/jquery-1.8.2.js"></script><script?type="text/javascript">//用來獲得option元素中selected屬性為true的元素的idfunction?Get_Selected_Id(place){var?pro?=?document.getElementById(place);var?Selected_Id?=?pro.options[pro.selectedIndex].id;
//????????????console.log("Get_Selected_Id:"+Selected_Id);??//測試使用return?Selected_Id;?????????//返回selected屬性為true的元素的id}//執行相應的動作,調用相關數據請求函數function?Get_Next_Place(This_Place_ID,Action){var?Selected_Id?=?Get_Selected_Id(This_Place_ID);???//Selected_Id用來記錄當前被選中的省或市的IDif(Action=='Get_city')????????????????????????????//從而可以在下一個級聯中加載相應的市或縣Get_City_Data(Selected_Id);else?if(Action=='Get_country')Get_Country_Data(Selected_Id);}//向服務器請求城市列表數據并調用添加城市函數function?Get_City_Data(Province_Selected_Id){????//這里的Selected_Id應該是被選中的省份的ID
//????????????console.log("Province_Selected_Id:"+Province_Selected_Id);???//測試使用if(Province_Selected_Id?==?'Not_data1'){????//如果選擇了"Province"選項,則表示重置當前City和Country的選項內容,不會向服務器請求數據$("#city").empty();$("#city").append("<option?id='Not_data2'>City</option>");$("#country").empty();$("#country").append("<option?id='Not_data3'>Country</option>");}else{??????//否則就會向服務器請求數據$.getJSON('/GetCityData/',{'Province':Province_Selected_Id},function(City_list){
//????????????????????console.log(City_list);??????//測試使用Add_city(City_list);????//調用添加城市選項函數});}}//在當前頁面添加城市選項function?Add_city(City_list){$("#city").empty();$("#city").append("<option?id='Not_data2'>City</option>");$("#country").empty();$("#country").append("<option?id='Not_data3'>Country</option>");//上面的兩次清空與兩次添加是為了保持級聯的一致性for(var?index?in?City_list){?????//獲得城市列表中的城市索引//添加內容的同時在option標簽中添加對應的城市IDvar?text?=?"<option"+"?id='"+City_list[index]+"'>"+City_list[index]+"</option>";$("#city").append(text);console.log(text);??//用來觀察生成的text數據}}//向服務器請求縣區列表數據并調用添加縣區函數function?Get_Country_Data(City_Selected_Id){
//???????????console.log("City_Selected_Id:"+City_Selected_Id);???//測試使用if(City_Selected_Id?==?'Not_data2'){?????//如果選擇了City選項,則表示重置當前Country的選項內容,不會向服務器請求數據$("#country").empty();$("#country").append("<option?id='Not_data3'>Country</option>");//上面的清空與添加是為了保持級聯的一致性}else{???//否則就會向服務器請求數據var?Province_Selected_ID?=?Get_Selected_Id("province");??//獲得被選中省的ID,從而方便從服務器中加載數據$.getJSON('/GetCountryData/',{'Province':Province_Selected_ID,'City':City_Selected_Id},function(Country_list){
//???????????????????console.log(Country_list);????//測試使用Add_country(Country_list);???//調用添加縣區選項函數});}}//在當前頁面添加縣區選項function?Add_country(Country_list){$("#country").empty();$("#country").append("<option?id='Not_data3'>Country</option>");//上面的清空與添加是為了保持級聯的一致性for(var?index?in?Country_list){?????//獲得縣區列表中的縣區索引//添加內容的同時在option標簽中添加對應的城市IDvar?text?=?"<option"+"?id='"+Country_list[index]+"'>"+Country_list[index]+"</option>";$("#country").append(text);console.log(text);??//用來觀察生成的text數據}}</script>
</head>
<body><p>您的收貨地址:</p><select?id="province"?οnchange="Get_Next_Place('province','Get_city')"><option?id="Not_data1">Province</option><option?id="GuangDong"?value="GuangDong">GuangDong</option><option?id="ShanDong"?value="ShanDong">ShanDong</option><option?id="HuNan"?value="HuNan">HuNan</option></select><select?id="city"?οnchange="Get_Next_Place('city','Get_country')"><option?id="Not_data2">City</option></select><select?id="country"><option?id="Not_data3">Country</option></select><br/>
</body>
</html>
????這里的代碼相對前面的就有點多,主要是因為在省市縣的級聯關系、數據的請求與添加上,需要進行相關的邏輯判斷,當然,仔細分析,這里的很多代碼都可以合并,時間關系,就不進行重構了。
4.測試與實現
????最終的結果是跟前面寫的那篇文章一樣的,只是不同的是,這里的數據都是來自Web服務器的,用戶的每一次點擊都會觸發一個事件,從而向服務器請求數據。
????就不多說了,有興趣的朋友可以試一試!
轉載于:https://blog.51cto.com/xpleaf/1716482
總結
以上是生活随笔為你收集整理的Django Web实现动态三级联动的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。