联动下拉菜单是Web开发中一个被经常使用的应用。比如当你从一个列表从选择一个国家的时候,联动下拉菜单会同步显示属于该国家所有城市列表供用户选择。今天我们就教你如何使用Django+Ajax生成联动下拉菜单。本案例使用Django 2.0 + Python 3.X开发,无需使用第三方安装包。
第一步创建APP,修改设置文件
创建一个叫dropdown的APP,并把它加到项目设置文件settings.py的INSTALLED_APP里去。如下图所示。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'dropdown',
]
同时把本应用urls加入到项目urls.py文件里去。
urlpatterns = [
path('admin/',admin.site.urls),
path('dropdown/',include('dropdown.urls')),
]
第二步 创建模型models.py
创建3个模型国家,城市和客户。其中City与Country是ForeignKey的关系。Client包含两个ForeignKey: City与Country。
fromdjango.dbimportmodels
fromdjango.urlsimportreverse
# Create your models here.
classCountry(models.Model):
name = models.CharField(verbose_name="国家",max_length=50)
def__str__(self):
returnself.name
classCity(models.Model):
name = models.CharField(verbose_name="城市",max_length=50)
country = models.ForeignKey(Country,on_delete=models.CASCADE,verbose_name="国家",)
def__str__(self):
returnself.name
classClient(models.Model):
name = models.CharField(verbose_name="客户",max_length=50)
country = models.ForeignKey(Country,on_delete=models.SET_NULL,null=True,verbose_name="国家")
city = models.ForeignKey(City,on_delete=models.SET_NULL,null=True,verbose_name="城市")
def__str__(self):
returnself.name
defget_absolute_url(self):
returnreverse('dropdown:client_detail',kwargs={'pk':self.pk})
第三步 编写urls.py
我们一共创建3个URL。一个创建用户,一个显示用户详情,还有一个处理Ajax发来的请求,返回Json数据给客户端。如果你不了解什么是Ajax及Ajax的工作方式,请阅读我们之前的文章【
Django实战:利用Ajax实现博文实时搜索
】
fromdjango.urlsimportpath,re_path
from.importviews
# namespace
app_name ='dropdown'
urlpatterns = [
#创建新客户
re_path(r'^client/create/$',views.ClientCreateView.as_view(),name='client_create'),
#显示客户详情
re_path(r'^client/(?P
\d+)/$',views.ClientDetailView.as_view(),name='client_detail'),
# Ajax调用城市清单
re_path(r'^ajax/load_cities/$',views.ajax_load_cities,name='ajax_load_cities'),
]
第四步 编写视图views.py
我们一共编写了3个处理方法,对应3个URL。
fromdjango.views.genericimportDetailView
fromdjango.views.generic.editimportCreateView
from.modelsimportClient,City
from.formsimportClientForm
fromdjango.httpimportJsonResponse
classClientCreateView(CreateView):
model = Client
form_class = ClientForm
template_name ='dropdown/client_form.html'
classClientDetailView(DetailView):
model = Client
defajax_load_cities(request):
ifrequest.method =='GET':
country_id = request.GET.get('country_id', None)
ifcountry_id:
data =list(City.objects.filter(country_id=country_id).values("id","name"))
returnJsonResponse(data,safe=False)
其中ajax_load_cities方法工作原理是这样子的:
如果ajax请求方法为GET,则获取country_id(这是实时变化的)。
Django查询所有属于country_id的城市对象,并获取其id和name,转化为字典形式。
Django通过JsonResponse方法将Json数据传给客户端。
它在后台工作,只是返回的数据并不以网页形式显示而已。
我们在本例中还使用了ClientForm创建Client,其代码如下:
fromdjangoimportforms
from.modelsimportClient
classClientForm(forms.ModelForm):
classMeta:
model = Client
fields = ["name","country","city"]
第五步 编写模板
#dropdown/templates/dropdown/client_form.html(用户创建)
{% block content %}
创建用户-联动下拉菜单
{% csrf_token %}
{{ form.as_p }}
Submit
{% endblock %}
其中ajax代码部分是这么工作的:
当id_country里的值有变化时,获取id_country的值, 变转化为字典。
ajax将country_id的值通过GET方法发送请求到 URL ‘/dropdown/ajax/load_cities/’
与该URL对应的视图ajax_load_cities处理ajax的请求,并返回Json格式的数据data
ajax接收数据成功后,就以each方法遍历Json数据,并将其显示在#id_city的DIV里。
第六步 查看效果
对比效果很明显,是不是?
领取专属 10元无门槛券
私享最新 技术干货