天天看点

Django Web实现动态三级联动

1.平台环境

    操作系统:Windows 7 64位

    开发环境:Eclipse PyDev

2.文件夹结构

    直接看下面的图片:

<a href="http://s1.51cto.com/wyfs02/M00/76/79/wKioL1ZULlvhko5KAAAz8NPmbRw173.png" target="_blank"></a>

    目前很多文件还用不上,在创建Django的项目时或app时,很多文件都是自动生成的,下面会说一说可以用得上的文件。

3.主要功能文件与代码

(1)MapPro/settings.py

    目前主要是用来设置statics和templates,告诉Django这两个目录的存在路径,添加的代码如下:

1

2

3

4

5

6

7

<code>TEMPLATE_DIRS </code><code>=</code> <code>(</code>

<code>                 </code><code>os.path.join(BASE_DIR,</code><code>'templates'</code><code>),</code>

<code>                 </code><code>)</code>

<code>STATICFILES_DIRS </code><code>=</code> <code>(</code>

<code>                    </code><code>os.path.join(BASE_DIR,</code><code>'statics'</code><code>),</code>

<code>                    </code><code>)</code>

(2)MapPro/urls.py

    设置url路径和views视图函数的映射关系,全部代码如下:

8

9

10

11

12

13

14

<code>from</code> <code>django.conf.urls </code><code>import</code> <code>patterns, include, url</code>

<code>from</code> <code>django.contrib </code><code>import</code> <code>admin</code>

<code>from</code> <code>app01 </code><code>import</code> <code>views</code>

<code>urlpatterns </code><code>=</code> <code>patterns('',</code>

<code>    </code><code># Examples:</code>

<code>    </code><code># url(r'^$', 'MapPro.views.home', name='home'),</code>

<code>    </code><code># url(r'^blog/', include('blog.urls')),</code>

<code>    </code><code>url(r</code><code>'^admin/'</code><code>, include(admin.site.urls)),</code>

<code>    </code><code>url(r</code><code>'^map/$'</code><code>,views.</code><code>Map</code><code>),</code>

<code>    </code><code>(r</code><code>'^GetCityData/$'</code><code>,views.Return_City_Data),</code>

<code>    </code><code>(r</code><code>'^GetCountryData/$'</code><code>,views.Return_Country_Data),</code>

<code>)</code>

(3)app01/views.py

    视图函数文件,用来处理业务逻辑,全部代码如下:

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

<code>from</code> <code>django.shortcuts </code><code>import</code> <code>render,render_to_response</code>

<code>from</code> <code>django.http </code><code>import</code> <code>HttpResponse</code>

<code>from</code> <code>django.core.context_processors </code><code>import</code> <code>request</code>

<code>import</code> <code>json</code>

<code># Create your views here.</code>

<code>def</code> <code>Map</code><code>(request):</code>

<code>    </code><code>return</code> <code>render_to_response(</code><code>"map.html"</code><code>)</code>

<code>    </code><code>#return HttpResponse("Hello!")</code>

<code>    </code> 

<code>Place_dict </code><code>=</code> <code>{</code>

<code>        </code><code>"GuangDong"</code><code>:{</code>

<code>                        </code><code>"GuangZhou"</code><code>:[</code><code>"PanYu"</code><code>,</code><code>"HuangPu"</code><code>,</code><code>"TianHe"</code><code>],</code>

<code>                        </code><code>"QingYuan"</code><code>:[</code><code>"QingCheng"</code><code>,</code><code>"YingDe"</code><code>,</code><code>"LianShan"</code><code>],</code>

<code>                        </code><code>"FoShan"</code><code>:[</code><code>"NanHai"</code><code>,</code><code>"ShunDe"</code><code>,</code><code>"SanShui"</code><code>]</code>

<code>                        </code><code>},</code>

<code>        </code><code>"ShanDong"</code><code>:{</code>

<code>                        </code><code>"JiNan"</code><code>:[</code><code>"LiXia"</code><code>,</code><code>"ShiZhong"</code><code>,</code><code>"TianQiao"</code><code>],</code>

<code>                        </code><code>"QingDao"</code><code>:[</code><code>"ShiNan"</code><code>,</code><code>"HuangDao"</code><code>,</code><code>"JiaoZhou"</code><code>]</code>

<code>        </code><code>"HuNan"</code><code>:{</code>

<code>                        </code><code>"ChangSha"</code><code>:[</code><code>"KaiFu"</code><code>,</code><code>"YuHua"</code><code>,</code><code>"WangCheng"</code><code>],</code>

<code>                        </code><code>"ChenZhou"</code><code>:[</code><code>"BeiHu"</code><code>,</code><code>"SuXian"</code><code>,</code><code>"YongXian"</code><code>]</code>

<code>                    </code><code>}</code>

<code>    </code><code>};</code>

<code>def</code> <code>Return_City_Data(request):</code>

<code>    </code><code>province </code><code>=</code> <code>request.GET[</code><code>'Province'</code><code>]</code>

<code>    </code><code>print</code> <code>province</code>

<code>    </code><code>City_list </code><code>=</code> <code>[]</code>

<code>    </code><code>for</code> <code>city </code><code>in</code> <code>Place_dict[province]:</code>

<code>        </code><code>City_list.append(city)</code>

<code>    </code><code>return</code> <code>HttpResponse(json.dumps(City_list))    </code>

<code>def</code> <code>Return_Country_Data(request):</code>

<code>    </code><code>province,city </code><code>=</code> <code>request.GET[</code><code>'Province'</code><code>],request.GET[</code><code>'City'</code><code>]</code>

<code>    </code><code>print</code> <code>province,city</code>

<code>    </code><code>Country_list </code><code>=</code> <code>Place_dict[province][city]</code>

<code>    </code><code>return</code> <code>HttpResponse(json.dumps(Country_list))</code>

    这里的代码比较简单,就不写注释了。

(4)templates/map.html

    templates目录主要用来放置页面的模板文件,这里我只创建map.html文件,代码如下:

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

<code>&lt;!DOCTYPE html&gt;</code>

<code>&lt;</code><code>html</code><code>&gt;</code>

<code>&lt;</code><code>head</code> <code>lang</code><code>=</code><code>"en"</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>meta</code> <code>charset</code><code>=</code><code>"UTF-8"</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>title</code><code>&gt;三级联动测试&lt;/</code><code>title</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>script</code> <code>src</code><code>=</code><code>"/static/jquery-1.8.2.js"</code><code>&gt;&lt;/</code><code>script</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>script</code> <code>type</code><code>=</code><code>"text/javascript"</code><code>&gt;</code>

<code>        </code><code>//用来获得option元素中selected属性为true的元素的id</code>

<code>        </code><code>function Get_Selected_Id(place){</code>

<code>            </code><code>var pro = document.getElementById(place);</code>

<code>            </code><code>var Selected_Id = pro.options[pro.selectedIndex].id;</code>

<code>//            console.log("Get_Selected_Id:"+Selected_Id);  //测试使用</code>

<code>            </code><code>return Selected_Id;         //返回selected属性为true的元素的id</code>

<code>        </code><code>}</code>

<code>        </code><code>//执行相应的动作,调用相关数据请求函数</code>

<code>        </code><code>function Get_Next_Place(This_Place_ID,Action){</code>

<code>            </code><code>var Selected_Id = Get_Selected_Id(This_Place_ID);   //Selected_Id用来记录当前被选中的省或市的ID</code>

<code>            </code><code>if(Action=='Get_city')                            //从而可以在下一个级联中加载相应的市或县</code>

<code>                </code><code>Get_City_Data(Selected_Id);</code>

<code>            </code><code>else if(Action=='Get_country')</code>

<code>                </code><code>Get_Country_Data(Selected_Id);</code>

<code>        </code><code>//向服务器请求城市列表数据并调用添加城市函数</code>

<code>        </code><code>function Get_City_Data(Province_Selected_Id){    //这里的Selected_Id应该是被选中的省份的ID</code>

<code>//            console.log("Province_Selected_Id:"+Province_Selected_Id);   //测试使用</code>

<code>            </code><code>if(Province_Selected_Id == 'Not_data1'){    //如果选择了"Province"选项,则表示重置当前City和Country的选项内容,不会向服务器请求数据</code>

<code>                </code><code>$("#city").empty();</code>

<code>                </code><code>$("#city").append("&lt;</code><code>option</code> <code>id</code><code>=</code><code>'Not_data2'</code><code>&gt;City&lt;/</code><code>option</code><code>&gt;");</code>

<code>                </code><code>$("#country").empty();</code>

<code>                </code><code>$("#country").append("&lt;</code><code>option</code> <code>id</code><code>=</code><code>'Not_data3'</code><code>&gt;Country&lt;/</code><code>option</code><code>&gt;");</code>

<code>            </code><code>}else{      //否则就会向服务器请求数据</code>

<code>                </code><code>$.getJSON('/GetCityData/',{'Province':Province_Selected_Id},function(City_list){</code>

<code>//                    console.log(City_list);      //测试使用</code>

<code>                    </code><code>Add_city(City_list);    //调用添加城市选项函数</code>

<code>                </code><code>});</code>

<code>            </code><code>}</code>

<code>        </code><code>//在当前页面添加城市选项</code>

<code>        </code><code>function Add_city(City_list){</code>

<code>            </code><code>$("#city").empty();</code>

<code>            </code><code>$("#city").append("&lt;</code><code>option</code> <code>id</code><code>=</code><code>'Not_data2'</code><code>&gt;City&lt;/</code><code>option</code><code>&gt;");</code>

<code>            </code><code>$("#country").empty();</code>

<code>            </code><code>$("#country").append("&lt;</code><code>option</code> <code>id</code><code>=</code><code>'Not_data3'</code><code>&gt;Country&lt;/</code><code>option</code><code>&gt;");</code>

<code>            </code><code>//上面的两次清空与两次添加是为了保持级联的一致性</code>

<code>            </code><code>for(var index in City_list){     //获得城市列表中的城市索引</code>

<code>                </code><code>//添加内容的同时在option标签中添加对应的城市ID</code>

<code>                </code><code>var text = "&lt;</code><code>option</code><code>"+" </code><code>id</code><code>=</code><code>'"+City_list[index]+"'</code><code>&gt;"+City_list[index]+"&lt;/</code><code>option</code><code>&gt;";</code>

<code>                </code><code>$("#city").append(text);</code>

<code>                </code><code>console.log(text);  //用来观察生成的text数据</code>

<code>        </code><code>//向服务器请求县区列表数据并调用添加县区函数</code>

<code>       </code><code>function Get_Country_Data(City_Selected_Id){</code>

<code>//           console.log("City_Selected_Id:"+City_Selected_Id);   //测试使用</code>

<code>           </code><code>if(City_Selected_Id == 'Not_data2'){     //如果选择了City选项,则表示重置当前Country的选项内容,不会向服务器请求数据</code>

<code>               </code><code>$("#country").empty();</code>

<code>               </code><code>$("#country").append("&lt;</code><code>option</code> <code>id</code><code>=</code><code>'Not_data3'</code><code>&gt;Country&lt;/</code><code>option</code><code>&gt;");</code>

<code>               </code><code>//上面的清空与添加是为了保持级联的一致性</code>

<code>           </code><code>}else{   //否则就会向服务器请求数据</code>

<code>               </code><code>var Province_Selected_ID = Get_Selected_Id("province");  //获得被选中省的ID,从而方便从服务器中加载数据</code>

<code>               </code><code>$.getJSON('/GetCountryData/',{'Province':Province_Selected_ID,'City':City_Selected_Id},function(Country_list){</code>

<code>//                   console.log(Country_list);    //测试使用</code>

<code>                   </code><code>Add_country(Country_list);   //调用添加县区选项函数</code>

<code>               </code><code>});</code>

<code>           </code><code>}</code>

<code>        </code><code>//在当前页面添加县区选项</code>

<code>        </code><code>function Add_country(Country_list){</code>

<code>            </code><code>//上面的清空与添加是为了保持级联的一致性</code>

<code>            </code><code>for(var index in Country_list){     //获得县区列表中的县区索引</code>

<code>                </code><code>var text = "&lt;</code><code>option</code><code>"+" </code><code>id</code><code>=</code><code>'"+Country_list[index]+"'</code><code>&gt;"+Country_list[index]+"&lt;/</code><code>option</code><code>&gt;";</code>

<code>                </code><code>$("#country").append(text);</code>

<code>    </code><code>&lt;/</code><code>script</code><code>&gt;</code>

<code>&lt;/</code><code>head</code><code>&gt;</code>

<code>&lt;</code><code>body</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>p</code><code>&gt;您的收货地址:&lt;/</code><code>p</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>select</code> <code>id</code><code>=</code><code>"province"</code> <code>onchange</code><code>=</code><code>"Get_Next_Place('province','Get_city')"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>option</code> <code>id</code><code>=</code><code>"Not_data1"</code><code>&gt;Province&lt;/</code><code>option</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>option</code> <code>id</code><code>=</code><code>"GuangDong"</code> <code>value</code><code>=</code><code>"GuangDong"</code><code>&gt;GuangDong&lt;/</code><code>option</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>option</code> <code>id</code><code>=</code><code>"ShanDong"</code> <code>value</code><code>=</code><code>"ShanDong"</code><code>&gt;ShanDong&lt;/</code><code>option</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>option</code> <code>id</code><code>=</code><code>"HuNan"</code> <code>value</code><code>=</code><code>"HuNan"</code><code>&gt;HuNan&lt;/</code><code>option</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>select</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>select</code> <code>id</code><code>=</code><code>"city"</code> <code>onchange</code><code>=</code><code>"Get_Next_Place('city','Get_country')"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>option</code> <code>id</code><code>=</code><code>"Not_data2"</code><code>&gt;City&lt;/</code><code>option</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>select</code> <code>id</code><code>=</code><code>"country"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>option</code> <code>id</code><code>=</code><code>"Not_data3"</code><code>&gt;Country&lt;/</code><code>option</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>br</code><code>/&gt;</code>

<code>&lt;/</code><code>body</code><code>&gt;</code>

<code>&lt;/</code><code>html</code><code>&gt;</code>

    这里的代码相对前面的就有点多,主要是因为在省市县的级联关系、数据的请求与添加上,需要进行相关的逻辑判断,当然,仔细分析,这里的很多代码都可以合并,时间关系,就不进行重构了。

4.测试与实现

    最终的结果是跟前面写的那篇文章一样的,只是不同的是,这里的数据都是来自Web服务器的,用户的每一次点击都会触发一个事件,从而向服务器请求数据。

    就不多说了,有兴趣的朋友可以试一试!

本文转自 xpleaf 51CTO博客,原文链接:http://blog.51cto.com/xpleaf/1716482,如需转载请自行联系原作者