You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Admin中如何通过下拉框值联动筛选城市选项?

Django Admin实现地址表单的州/省-城市联动筛选

先修正你代码里的基础问题

  1. 模型拼写错误:Adrress 改为 Address,City 模型里的 cityـname 存在特殊字符,改为 city_name,避免后续字段调用出错。
  2. 之前的自定义Widget方案存在硬编码数据、JS操作逻辑错误等问题,改用AJAX动态获取数据的方式更可靠。

步骤1:添加AJAX接口获取对应州的城市

在项目的views.py中添加视图:

from django.http import JsonResponse
from .models import City

def get_cities_by_state(request):
    state_id = request.GET.get('state_id')
    # 根据选中的州ID过滤城市,返回ID和名称
    cities = City.objects.filter(state_id=state_id).values('id', 'city_name')
    return JsonResponse(list(cities), safe=False)

在项目根urls.py中添加路由:

from django.urls import path
from . import views

urlpatterns = [
    # 其他原有路由
    path('admin/get-cities/', views.get_cities_by_state, name='get_cities_by_state'),
]

步骤2:自定义Admin表单

在forms.py中编写表单,添加州选择字段并处理初始值:

from django import forms
from .models import Address, State, City

class AddressAdminForm(forms.ModelForm):
    # 添加州选择字段,用于触发联动
    state = forms.ModelChoiceField(
        queryset=State.objects.all(),
        required=True,
        label="州/省"
    )

    class Meta:
        model = Address
        fields = ['user', 'state', 'city', 'description']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 编辑地址时,自动选中对应州并加载城市
        if self.instance.pk:
            self.fields['state'].initial = self.instance.city.state
            self.fields['city'].queryset = City.objects.filter(state=self.instance.city.state)
        else:
            # 新建地址时,默认城市下拉框为空
            self.fields['city'].queryset = City.objects.none()

步骤3:修改Admin类并引入JS

在admin.py中更新地址的Admin配置,引入自定义JS:

from django.contrib import admin
from .models import State, City, Address
from .forms import AddressAdminForm

@admin.register(State)
class StateAdmin(admin.ModelAdmin):
    list_display = ('state_name',)

@admin.register(City)
class CityAdmin(admin.ModelAdmin):
    list_display = ('city_name', 'state')

@admin.register(Address)
class AddressAdmin(admin.ModelAdmin):
    form = AddressAdminForm

    class Media:
        # 引入Django Admin自带的jQuery,避免版本冲突
        js = (
            'admin/js/jquery.js',
            'js/address_city_filter.js',
        )

步骤4:编写联动JS逻辑

在项目static/js/目录下创建address_city_filter.js:

(function($) {
    $(document).ready(function() {
        const stateSelect = $('#id_state');
        const citySelect = $('#id_city');

        // 监听州选择变化
        stateSelect.change(function() {
            const stateId = $(this).val();
            if (stateId) {
                $.ajax({
                    url: '/admin/get-cities/',
                    data: { 'state_id': stateId },
                    dataType: 'json',
                    success: function(data) {
                        citySelect.empty();
                        citySelect.append('<option value="">请选择城市</option>');
                        $.each(data, function(index, city) {
                            citySelect.append(`<option value="${city.id}">${city.city_name}</option>`);
                        });
                    },
                    error: function() {
                        citySelect.empty();
                        citySelect.append('<option value="">加载城市失败</option>');
                    }
                });
            } else {
                citySelect.empty();
                citySelect.append('<option value="">请先选择州/省</option>');
            }
        });

        // 页面加载时,若有默认州则触发一次联动
        if (stateSelect.val()) {
            stateSelect.trigger('change');
        }
    });
})(django.jQuery);

最后部署注意事项

  1. 运行python manage.py collectstatic,将静态文件收集到指定目录
  2. 确保所有模型字段名的拼写错误已修正
  3. 测试新增/编辑地址时的联动效果

内容的提问来源于stack exchange,提问作者user25495429

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:48:12