Django无需额外创建国家城市模型实现联动下拉框咨询
实现方案
1. 模型字段定义
不需要给城市字段做特殊关联,直接用CharField存储城市名称即可,替换你代码里的school_city = ??部分:
school_city = models.CharField(max_length=100, verbose_name="学校所在城市")
修改后执行python manage.py makemigrations和python manage.py migrate完成数据库变更。
2. 后端接口开发
django-cities已经内置了国家、城市的预定义模型,你不需要手动创建对应模型,完成django-cities的初始化迁移后直接调用即可。首先编写接口根据传入的国家代码返回对应城市列表:
视图代码
# views.py from django.http import JsonResponse from cities.models import City, Country def get_cities_by_country(request): country_code = request.GET.get('country_code') if not country_code: return JsonResponse({'cities': []}) country = Country.objects.filter(code=country_code.upper()).first() if not country: return JsonResponse({'cities': []}) cities = City.objects.filter(country=country).values('name') return JsonResponse({'cities': list(cities)})
路由配置
# 项目/应用的urls.py from django.urls import path from . import views urlpatterns = [ # 原有路由 path('api/get_cities/', views.get_cities_by_country, name='get_cities'), ]
3. 前端联动逻辑
在表单渲染模板中加入监听逻辑,选中国家后自动请求接口加载城市选项:
<form method="post" enctype="multipart/form-data"> {% csrf_token %} <div> <label>学校国家:</label> {{ form.school_country }} </div> <div> <label>学校城市:</label> <select name="school_city" id="id_school_city" required> <option value="">请先选择国家</option> </select> </div> <!-- 其他表单字段 --> <button type="submit">提交</button> </form> <script> const countrySelect = document.getElementById('id_school_country'); const citySelect = document.getElementById('id_school_city'); countrySelect.addEventListener('change', () => { const countryCode = countrySelect.value; citySelect.innerHTML = '<option value="">加载中...</option>'; if (!countryCode) { citySelect.innerHTML = '<option value="">请先选择国家</option>'; return; } fetch(`/api/get_cities/?country_code=${countryCode}`) .then(res => res.json()) .then(data => { let html = '<option value="">请选择城市</option>'; data.cities.forEach(item => { html += `<option value="${item.name}">${item.name}</option>`; }); citySelect.innerHTML = html; }) .catch(() => { citySelect.innerHTML = '<option value="">加载失败,请重试</option>'; }); }); </script>
4. 表单验证(可选)
如果需要校验提交的城市是否属于所选国家,可以新增表单类做校验:
# forms.py from django import forms from .models import School from cities.models import City, Country class SchoolForm(forms.ModelForm): class Meta: model = School fields = '__all__' def clean(self): cleaned_data = super().clean() country = cleaned_data.get('school_country') city = cleaned_data.get('school_city') if country and city: country_ins = Country.objects.filter(code=country.code).first() if not City.objects.filter(country=country_ins, name=city).exists(): raise forms.ValidationError("所选城市不属于当前国家") return cleaned_data
内容的提问来源于stack exchange,提问作者Sista-Night
相关产品推荐
相关产品推荐

