django-使用jquery完成ajax,实例-选择省市区
使用Ajax
- 使用视图通过上下文向模板中传递数据,需要先加载完成模板的静态页面,再执行模型代码,生成最张的html,返回给浏览器,这个过程将页面与数据集成到了一起,扩展性差
- 改进方案:通过ajax的方式获取数据,通过dom操作将数据呈现到界面上
- 推荐使用框架的ajax相关方法,不要使用XMLHttpRequest对象,因为操作麻烦且不容易查错
- jquery框架中提供了$.ajax、$.get、$.post方法,用于进行异步交互
- 由于csrf的约束,推荐使用$.get
- 示例:实现省市区的选择
- 最终实现效果如图:

引入js文件
- js文件属于静态文件,创建目录结构如图:

修改settings.py关于静态文件的设置
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
在models.py中定义模型
class AreaInfo(models.Model):
title=models.CharField(max_length=20)
parea=models.ForeignKey('self',on_delete=models.CASCADE,null=True,blank=True)
settings.py文件INSTALLED_APPS添加app
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'booktest',
]
修改settings.py关于DATABASES的设置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ttsx1',
'USER':'root',
'PASSWORD':'mysql123',
'HOST':'localhost',
'PORT':3306
}
}
生成迁移
python manage.py makemigrations
python manage.py migrate
通过Navicat向表中填充示例数据
- 参见“省市区.sql”
- 注意将表的名称完成替换

在views.py中编写视图
- index用于展示页面
- pro用于返回省级数据
- city用于根据省、市编号返回市、区信息,格式都为字典对象
1 from django.shortcuts import render 2 from .models import * 3 from django.http import HttpResponse,JsonResponse 4 5 # Create your views here. 6 7 def index(request): 8 return render(request,'booktest/index.html') 9 10 #省的信息 11 def pro(request): 12 data=AreaInfo.objects.filter(parea__isnull=True) 13 list=[] 14 #[[1,北京],[2,河北],...] 15 for pro in data: 16 list.append([pro.id,pro.title]) 17 return JsonResponse({'data':list}) 18 19 #市和区的信息 20 def city(request,id): 21 data=AreaInfo.objects.filter(parea_id=id) 22 list=[] 23 #[{id:1,title:北京},{id:2,title:河北},...] 24 for city in data: 25 list.append({'id':city.id,'title':city.title}) 26 return JsonResponse({'data':list})
在urls.py中配置urlconf
1 from django.conf.urls import url,include 2 from . import views 3 4 urlpatterns = [ 5 url(r'^index/$',views.index), 6 url(r'^pro/$',views.pro), 7 url(r'^city(\d+)/$',views.city), 8 ]
主urls.py中包含此应用的url
1 from django.contrib import admin 2 from django.urls import path 3 from django.conf.urls import url,include 4 5 urlpatterns = [ 6 path('admin/', admin.site.urls), 7 url(r'^',include('booktest.urls')) 8 ]
定义模板index.html
- 在项目中的目录结构如图:

- 修改settings.py的TEMPLATES项,设置DIRS值
'DIRS': [os.path.join(BASE_DIR,'templates')],
-
定义模板文件:
-
包含三个select标签,分别存放省市区的信息
-
在模板中引入jquery文件
-
编写js代码
- 绑定change事件
- 发出异步请求
- 使用dom添加元素
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>index</title> 6 <script src="/static/booktest/jquery-1.12.4.min.js"></script> 7 <script> 8 $(function(){ 9 //使用ajax加载省信息 10 pro=$('#pro') 11 $.get('/pro/',function(dic){ //dic格式为{data:[[],[],[],]} 12 $.each(dic.data,function(index,item){ //item格式为[id,title] 13 pro.append('<option value="'+item[0]+'">'+item[1]+'</option>') //节点操作,添加元素 14 }) 15 }); 16 17 //获取市的信息 18 $('#pro').change(function(){ 19 //alert($(this).val()) //弹出省对应的value值 20 $.get('/city'+$(this).val()+'/',function(dic){ //dic格式为{data:[{},{}...]} 21 city=$('#city') 22 city.empty().append('<option value="">请选择市</option>') //empty()把所有段落的子元素(包括文本节点)删除 23 $('#dis').empty().append('<option value="">请选择区</option>') 24 $.each(dic.data,function(index,item){ 25 city.append('<option value="'+item.id+'">'+item.title+'</option>') 26 }) 27 }) 28 }); 29 30 //获取区的信息 31 $('#city').change(function(){ 32 $.get('/city'+$(this).val()+'/',function(dic){ 33 dis=$('#dis') 34 dis.empty().append('<option value="">请选择区</option>') 35 $.each(dic.data,function(index,item){ 36 dis.append('<option value="'+item.id+'">'+item.title+'</option>') 37 }) 38 }) 39 }) 40 }) 41 </script> 42 43 </head> 44 <body> 45 <select id="pro"> 46 <option value="">请选择省</option> 47 </select> 48 <select id="city"> 49 <option value="">请选择市</option> 50 </select> 51 <select id="dis"> 52 <option value="">请选择区</option> 53 </select> 54 </body> 55 </html>

补充:
自连接
- 对于地区信息,属于一对多关系,使用一张表,存储所有的信息
- 类似的表结构还应用于分类信息,可以实现无限级分类
- 新建模型AreaInfo,生成迁移
class AreaInfo(models.Model):
atitle = models.CharField(max_length=20)
aParent = models.ForeignKey('self', null=True, blank=True)
- 访问关联对象
上级对象:area.aParent
下级对象:area.areainfo_set.all()
- 加入测试数据(在workbench中,参见“省市区mysql.txt”)
- 在booktest/views.py中定义视图area
from models import AreaInfo
def area(request):
area = AreaInfo.objects.get(pk=130100)
return render(request, 'booktest/area.html', {'area': area})
- 定义模板area.html
<!DOCTYPE html>
<html>
<head>
<title>地区</title>
</head>
<body>
当前地区:{{area.atitle}}
<hr/>
上级地区:{{area.aParent.atitle}}
<hr/>
下级地区:
<ul>
{ %for a in area.areainfo_set.all%}
<li>{{a.atitle}}</li>
{ %endfor%}
</ul>
</body>
</html>
- 在booktest/urls.py中配置一个新的urlconf
urlpatterns = [
url(r'^area/$', views.area, name='area')
]
posted on 2020-02-02 11:01 cherry_ning 阅读(326) 评论(0) 收藏 举报
浙公网安备 33010602011771号