需求
在项目中使用Django admin作为后台管理,在店铺表编辑页面需要设置省市区三级联动,查了很多资源,没有发现原生支持的联动方式。 在网上借鉴了别人的写法。
配置:
步骤
在app文件下创建templates文件夹,创建shop_detail.html用于复写店铺编辑页。 文件名字可自定义。
在app的admin.py中增加并注册ShopAdmin类,在类中增加change_form_template = "shop_detail.html",指向的html文件名和1中的一致。
从当前python环境中,找到Django包,复制里面的chang_form.html全部内容到前面创建的html中。 该html具体地址为python3.7/site-packages/django/contrib/admin/templates/admin/change_form.html。
编辑shop_detail.html
- 将以下ajax请求增加到替换到
admin_change_form_document_ready的block中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 40 41 42 43 44 45 46 47 48 49
| {% block admin_change_form_document_ready %} <script type="text/javascript"> (function($) { $(document).ready(function() { $('.add-another').click(function(e) { e.preventDefault(); var event = $.Event('django:add-another-related'); $(this).trigger(event); if (!event.isDefaultPrevented()) { showAddAnotherPopup(this); } });
{% if adminform and add %} $('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus() {% endif %} }); $.get('/common/choose/province/',function(p_info){ // 获取省份接口 这里的地址自定义,已实际的接口地址为准 var province_info = $('#id_province').empty().append('<option value>'+'---------'+'</option>'); // id_province 已实际的省份字段名为准,可在admin页面中查找 $.each(p_info.p_lists,function(i,province){ province_info.append('<option value="'+province.p_id+'">'+province.p_name+'</option>') });
$('#id_province').change(function(){ p_id = $(this).val(); $.get('/common/choose/city/',{'p_id':p_id},function(c_info){ // 获取城市接口 这里的地址自定义,已实际的接口地址为准 var city_info = $('#id_city').empty().append('<option value>'+'---------'+'</option>'); // id_city 已实际的城市字段名为准,可在admin页面中查找 $.each(c_info.c_lists,function(i,city){ city_info.append('<option value="'+city.c_id+'">'+city.c_name+'</option>') }) }) });
$('#id_city').change(function(){ c_id = $(this).val(); $.get('/common/choose/area/',{"c_id": c_id},function(a_info){ // 获取地区接口 这里的地址自定义,已实际的接口地址为准 var area_info = $('#id_district').empty().append('<option value>'+'---------'+'</option>'); // id_district 已实际的地区字段名为准,可在admin页面中查找 $.each(a_info.a_lists,function(i,area){ area_info.append('<option value="'+area.a_id+'">'+area.a_name+'</option>') }); }); }); }); })(django.jQuery); </script> {% endblock %}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| def choose_province(request): """查询省""" provinces = Area.objects.filter(parent=None) p_lists = [{"p_id": province.id, "p_name": province.name} for province in provinces] p_info = {"p_lists": p_lists} return JsonResponse(p_info, safe=False)
def choose_city(request): """查询市""" p_id = request.GET.get('p_id') print(p_id, '--------') if not p_id: return JsonResponse({}, safe=False) citys = Area.objects.filter(parent_id=p_id) c_lists = [{"c_id": city.id, "c_name": city.name} for city in citys] print(c_lists[0:5]) c_info = {"c_lists": c_lists} return JsonResponse(c_info, safe=False)
def choose_area(request): """查询区""" c_id = request.GET.get('c_id') print(c_id, '=======') if not c_id: return JsonResponse({}, safe=False) areas = Area.objects.filter(parent_id=c_id) print(areas) a_lists = [{"a_id": area.id, "a_name": area.name} for area in areas] a_info = {"a_lists": a_lists} print(a_info) return JsonResponse(a_info, safe=False)
|
1 2 3
| url(r'^choose/province/$', views.choose_province), url(r'^choose/city/$', views.choose_city), url(r'^choose/area/$', views.choose_area),
|
总结
Django admin功能比较齐全,以前只是按照文档使用,并没有涉及到修改页面。 通过这个3级联动,也清楚了admin的部分原理。对于一些复杂的页面,可以用自定义的形式来重构页面。