Django下三級/多級聯動的解決辦法


 最終實現效果:

類似  國家 -> 省 -> 市 這樣的多級分類聯動下拉列表在各種項目中都經常用到,但是放狗搜了半天也沒有一套Django完整的解決教程,最接近的是 芝麻問答 ,但也只是在模型上簡單描述了思路,離最終的完成還有一段距離。所以,只有自己動手了…

思路:

普通Html頁面下多級聯動的實現是通過對<OPTION>進行動作綁定,一旦發生數據改變就對子類別的下拉列表進行更新。Django於此相異的地方主要在於后台數據的傳遞,我們只要建立一個分類數據讀取接口,然后將從數據庫中讀出的相關值生成JSON格式傳遞到前台頁面即可。
在數據庫的設計上,我想盡量簡單,只是用三個字段來實現無線分類,分別是id,name,pid(父級分類ID);另外由於分類並非經常更改,但要經常讀取,為了避免不必要的數據庫開銷,我將每次更新后的分類數據生成一個靜態JS格式文件供前台讀取。

實現代碼:

首先是選擇前台頁面的JS聯動代碼,感謝“YAODAYIZI”提供的腳本,具體如下:

1.表現層Html頁面(category_list.html):

01 <!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
02 <html>
03     <head>
04         <title>
05             Django Learning 下拉列表多級聯動選擇
06         </title>
07         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
08         <script language="javascript">
09             function Dlist(array) {
10                 this.array = array;
11                 this.indexName = '';
12                 this.obj = '';
13                 this.subSelectChange = function(selectName1, selectName2) {
14                     var obj1 = document.all[selectName1];
15                     var obj2 = document.all[selectName2];
16                     var objName = this.toString();
17                     var me = this;
18                     obj1.onchange = function() {
19                         me.optionChange(this.options[this.selectedIndex].value, obj2.id)
20                     }
21                 }
22                 this.firstSelectChange = function(indexName, selectName) {
23                     this.obj = document.all[selectName];
24                     this.indexName = indexName;
25                     this.optionChange(this.indexName, this.obj.id)
26                 }
27                 this.optionChange = function(indexName, selectName) {
28                     var obj1 = document.all[selectName];
29                     var me = this;
30                     obj1.length = 0;
31                     obj1.options[0] = new Option("請選擇", '');
32                     for (var i = 0; i < this.array.length; i++) {
33                         if (this.array[i][1] == indexName) {
34                             obj1.options[obj1.length] = new Option(this.array[i][2], this.array[i][0])
35                         }
36                     }
37                 }
38             }
39         </script>
40     </head>
41  
42     <body>
43         <a href="?mode=reset">
44             重建靜態文件
45         </a>
46         <form name="form1" method="post">
47             <SELECT ID="s1" NAME="s1" size="10">
48                 <OPTION selected>
49                 </OPTION>
50             </SELECT>
51             <SELECT ID="s2" NAME="s2" size="10">
52                 <OPTION selected>
53                 </OPTION>
54             </SELECT>
55             <SELECT ID="s3" NAME="s3" size="10">
56                 <OPTION selected>
57                 </OPTION>
58             </SELECT>
59         </form>
60         <script type="text/javascript" src="/static/js/category_data.js"><!-- 此處根據你的category_data.js存放位置進行更改-->
61         </script>
62         <script type="text/javascript">
63             var liandong = new Dlist(array) liandong.firstSelectChange("0", "s1");<!-- 聯動關系設置-->
64             liandong.subSelectChange("s1", "s2");
65             liandong.subSelectChange("s2", "s3");
66         </script>
67         <hr>
68         <div>
69             Thanks for visiting.
70         </div>
71     </body>
72 </html>

2.Model類

1 class Category(models.Model):
2     c_name = models.CharField(max_length=20,help_text="類別名稱")
3     c_father = models.IntegerField(max_length=4,default=0,help_text="父級類別ID")
4     c_hidden = models.BooleanField(default=0,blank=True)
5  
6     def __unicode__(self):
7         return (u'%d,%d,%s'% (self.id,self.c_father,self.c_name)

3. 根據數據庫生成的JS數據文件(category_data.js):

01 var array=new Array();
02 array[0]=new Array('1','0','羅萊'//id,pid,name
03 array[1]=new Array('2','0','優家')
04 array[2]=new Array('3','0','寶縵')
05 array[3]=new Array('4','0','其他')
06 array[4]=new Array('5','1','芯類')
07 array[5]=new Array('6','1','家居類')
08 array[6]=new Array('7','5','被芯')
09 array[7]=new Array('8','5','枕芯')
10 array[8]=new Array('9','2','新經典')
11 array[9]=new Array('10','2','新優雅')

4. 根據數據庫生成的category_data的辦法(view.py):< /strong>

01 import codecs
02 def category_manage(request):
03     if request.GET.has_key('mode'):
04         mode = request.GET['mode']
05         if mode == 'reset':
06             jfile = codecs.open('static/js/category_data.js','w','utf-8')#Python3.0以上版本可以直接使用f.open(...,'encoding':'utf-8')
07             jfile.write("var array=new Array();\n")
08             clist = Category.objects.all()
09             for in clist:
10                 jfile.write ("array[%d]=new Array('%d','%d','%s')\n"%(c.id-1,c.id,c.c_father,c.c_name))
11             jfile.close()
12     return render_to_response('category.html',locals())

到這里已經完成的七七八八了,然后去url.py下配置好相關路徑就可以運行了,如果你希望直接從數據庫中讀取或者希望和Form類緊密關聯,修改起來也會比較容易,有時間的話下次我再另外發一篇練習文章。
希望以上的內容對你有所幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM