django admin后台 城市的三级条件联动

原理是通过更改模板中的js,然后使用ajax异步获取选项。

1、首先找到模板change_form.html并复制到templates中

2、然后找到要更改的字段id,手动F12查找

3、然后更改模板,添加js代码(注意放在endblock前)

以下为新增代码

<script type="text/javascript">    

document.addEventListener('DOMContentLoaded', function () {
    const sheSelect = document.getElementById('id_shen');
    const shiSelect = document.getElementById('id_locity');
    const quSelect  = document.getElementById('id_dist');

    function addEmptyOption(selectElement) {
        //设置默认空选项
        const emptyOption = document.createElement('option');
        emptyOption.value = '';
        emptyOption.text = '---------';
        selectElement.add(emptyOption, 0);
    }

    function resetSelect(selectElement) {
        //清空所有选项并设置为空
        selectElement.length = 0;
        addEmptyOption(selectElement);
    };
    // addEmptyOption(shiSelect);
    // addEmptyOption(quSelect);



    sheSelect.addEventListener('change', function () {
        const shenId = this.value;
        // provinceSelect.length = 0;
        resetSelect(shiSelect);
        resetSelect(quSelect);

        if (!shenId) {
            return;
        }
        const url = '/api/ZZZZ/'+shenId
        fetch(url)
            .then(response => response.json())
            .then(data => {
                for (const key in data) {
                    const option = document.createElement('option');
                    option.value = key;
                    option.text = data[key];
                    shiSelect.add(option);
                }
            });
    });

    shiSelect.addEventListener('change', function () {
        const shiId = this.value;
        resetSelect(quSelect);

        if (!shiId) {
            return;
        }
        const url = '/api/XXXX/'+shiId
        fetch(url)
            .then(response => response.json())
            .then(data => {
                for (const key in data) {
                    const option = document.createElement('option');
                    option.value = key;
                    option.text = data[key];
                    quSelect.add(option);
                }
            });
    });



});
</script>

这里要注意admin.py 中有联动的字段不能在 autocomplete_fields 中,不然会无效。

PS:以下为gpt参考资料,经测试可用:

在Django admin后台实现三级联动菜单需要进行以下几个步骤:

  1. 创建模型:定义三个相关联的模型,例如国家、省份和城市。

  2. 注册模型到admin后台:在admin.py文件中注册这些模型。

  3. 实现联动逻辑:利用Django 视图和JavaScript实现三级联动。

下面是一个详细的示例:

1. 创建模型

在你的models.py文件中定义三个模型:国家(Country)、省份(Province)和城市(City)。

from django.db import models

class Country(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Province(models.Model):
    name = models.CharField(max_length=100)
    country = models.ForeignKey(Country, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class City(models.Model):
    name = models.CharField(max_length=100)
    province = models.ForeignKey(Province, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

2. 注册模型到admin后台

在你的admin.py文件中注册这些模型。

from django.contrib import admin
from .models import Country, Province, City

admin.site.register(Country)
admin.site.register(Province)
admin.site.register(City)

Django视图返回字典格式的JSON响应

from django.http import JsonResponse
from .models import Province, City

def province_by_country(request, country_id):
    provinces = Province.objects.filter(country_id=country_id).order_by('name')
    province_dict = {province.id: province.name for province in provinces}
    return JsonResponse(province_dict)

def city_by_province(request, province_id):
    cities = City.objects.filter(province_id=province_id).order_by('name')
    city_dict = {city.id: city.name for city in cities}
    return JsonResponse(city_dict)

更新URL配置 (urls.py)

from django.urls import path
from . import views

urlpatterns = [
    path('admin/app_name/province_by_country/<int:country_id>/', views.province_by_country, name='province_by_country'),
    path('admin/app_name/city_by_province/<int:province_id>/', views.city_by_province, name='city_by_province'),
]

3. 实现联动逻辑

使用JavaScript来实现联动逻辑。

document.addEventListener('DOMContentLoaded', function () {
    const countrySelect = document.getElementById('id_country');
    const provinceSelect = document.getElementById('id_province');
    const citySelect = document.getElementById('id_city');

    function addEmptyOption(selectElement) {
        const emptyOption = document.createElement('option');
        emptyOption.value = '';
        emptyOption.text = '请选择';
        selectElement.add(emptyOption, 0);
    }

    function resetSelect(selectElement) {
        selectElement.length = 0;
        addEmptyOption(selectElement);
    }

    addEmptyOption(provinceSelect);
    addEmptyOption(citySelect);

    countrySelect.addEventListener('change', function () {
        const countryId = this.value;
        resetSelect(provinceSelect);
        resetSelect(citySelect);

        if (!countryId) {
            return;
        }

        fetch(`/admin/app_name/province_by_country/${countryId}/`)
            .then(response => response.json())
            .then(data => {
                for (const key in data) {
                    const option = document.createElement('option');
                    option.value = key;
                    option.text = data[key];
                    provinceSelect.add(option);
                }
            });
    });

    provinceSelect.addEventListener('change', function () {
        const provinceId = this.value;
        resetSelect(citySelect);

        if (!provinceId) {
            return;
        }

        fetch(`/admin/app_name/city_by_province/${provinceId}/`)
            .then(response => response.json())
            .then(data => {
                for (const key in data) {
                    const option = document.createElement('option');
                    option.value = key;
                    option.text = data[key];
                    citySelect.add(option);
                }
            });
    });
});

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值