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

如何修复django-forms-dynamic中对象与章节下拉菜单未关联问题

Django Forms Dynamic 三级联动修复方案

问题根源分析

你的表单中对象与章节未关联的核心原因有三个:

  1. contractor_section 字段未声明依赖 contractor_object,导致django-forms-dynamic无法监听对象字段的变化来更新章节选项
  2. section_choices 中直接使用字符串类型的对象ID进行过滤,与外键字段的类型不匹配
  3. initial_sections 返回单个对象,不符合ModelMultipleChoiceField对初始值的可迭代要求

修复代码

1. 修改 forms.py

class WorkLogForm(DynamicFormMixin, forms.ModelForm):

    def object_choices(form):
        contractor_counter = form['contractor_counter'].value()
        object_query = ObjectList.objects.filter(contractor_guid__in=[contractor_counter])
        return object_query

    def initial_object(form):
        contractor_counter = form['contractor_counter'].value()
        object_query = ObjectList.objects.filter(contractor_guid__in=[contractor_counter])
        return object_query.first()

    def section_choices(form):
        contractor_object_id = form['contractor_object'].value()
        # 转成整数匹配外键ID类型,无值时返回空查询集
        if contractor_object_id:
            section_query = SectionList.objects.filter(object_id=int(contractor_object_id))
            return section_query
        return SectionList.objects.none()

    def initial_sections(form):
        contractor_object_id = form['contractor_object'].value()
        if contractor_object_id:
            section_obj = SectionList.objects.filter(object_id=int(contractor_object_id)).first()
            return [section_obj] if section_obj else []  # 返回列表适配多选字段
        return []

    contractor_counter = forms.ModelChoiceField(
        label='Контрагент',
        queryset=CounterParty.objects.all(),  # 修正初始无选项问题
        initial=CounterParty.objects.first(),
        empty_label='',
    )

    contractor_object = DynamicField(
        forms.ModelChoiceField,
        label='Объект',
        queryset=object_choices,
        initial=initial_object,
        depends_on='contractor_counter',  # 明确依赖交易对手字段
    )

    contractor_section = DynamicField(
        forms.ModelMultipleChoiceField,
        label='Раздел',
        queryset=section_choices,
        initial=initial_sections,
        depends_on='contractor_object',  # 关键:添加对象字段依赖
        widget=forms.SelectMultiple(),
    )

2. 确认 views.py 视图逻辑

确保contractor_section视图能正确接收对象参数:

def contractor_section(request):
    form = WorkLogForm(request.GET, user=request.user)
    return HttpResponse(form['contractor_section'])

3. 前端联动补充(示例)

确保对象字段变化时触发章节下拉框更新:

$('#id_contractor_object').change(function() {
    const objectId = $(this).val();
    $.get('/your-url/contractor_section/', {contractor_object: objectId}, function(data) {
        $('#id_contractor_section').html(data);
    });
});

额外说明

  • 修正了contractor_counter初始无选项的问题,将queryset改为CounterParty.objects.all()
  • 给section_choices添加空值判断,避免类型转换报错
  • 调整initial_sections返回格式,匹配多选字段对初始值的可迭代要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:32:28