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

Django ModelForm ce_hostname下拉按订单过滤为空问题

问题原因

当前下拉框空白的核心原因是表单初始化与参数赋值顺序错误:

  • 视图中先执行Cx_BaseForm()实例化,这一步已经跑完了表单__init__方法里的ce_hostname查询集过滤逻辑,此时self.instance.order_reference默认是空值None,过滤出来的Ce_Base结果为空集
  • 实例化完成后才给cx_base_form.instance.order_reference赋值,这个后置操作不会重新触发下拉框查询集的计算,所以下拉框始终显示空白
  • 硬编码order_reference='1'时过滤逻辑不依赖未赋值的instance属性,所以能正常运行
修复方案

修改forms.py

不要从self.instance取订单对象做过滤,改成通过初始化参数显式传入当前订单,避免时序问题:

class Cx_BaseForm(ModelForm):
    class Meta:
        model = Cx_Base
        fields = ['cx_hostname', 'new', 'ce_hostname', 'location', 'manged_module_model', 'slot']

    def __init__(self, *args, **kwargs):
        # 从初始化参数中弹出提前传入的current_order,避免传给父类ModelForm触发参数错误
        current_order = kwargs.pop('current_order', None)
        super(Cx_BaseForm, self).__init__(*args, **kwargs)
        # 拿到传入的订单对象后再执行过滤
        if current_order is not None:
            self.fields['ce_hostname'].queryset = Ce_Base.objects.filter(order_reference=current_order)
        else:
            # 兜底逻辑,未传订单时返回空查询集,避免泄露全量CE主机数据
            self.fields['ce_hostname'].queryset = Ce_Base.objects.none()

修改views.py

不管是GET请求渲染空表单,还是POST请求处理提交,实例化表单时都直接传入当前订单对象,保证表单初始化阶段就能拿到过滤参数:

@login_required
def addCX_Base(request, pk_test):
    order = Order.objects.get(id=pk_test)
    # GET请求实例化表单时直接传入current_order参数
    cx_base_form = Cx_BaseForm(current_order=order)
    
    if request.method == 'POST':
        # POST请求实例化表单时也要传current_order,避免表单校验失败重渲染时下拉框再次变空
        cx_base_form = Cx_BaseForm(request.POST, current_order=order)
        # 保留实例绑定订单的逻辑,保证数据保存时关联关系正确
        cx_base_form.instance.order_reference = order
        
        if request.POST.get("new") == "on":
            print(request.POST.get("new"))
        else:
            for managed_module in inventory["managed_modules"]:
                print(managed_module["model"])
                model = request.POST.get("manged_module_model")
                print(model)
                if model == managed_module["model"]:
                    print(managed_module["l2_ports"])
                    cx_base_form.instance.l2_interfaces = managed_module["l2_ports"]
            if cx_base_form.is_valid():
                cx_base_form.save()
                return redirect('/')
            else:
                print("Form is not valid")

    context = {'cx_base_form':cx_base_form}
    return render(request, 'orchestration/cx_base_form.html', context)

注意:不要依赖「先实例化表单再给instance赋值」的方式传递动态过滤参数,因为__init__里的字段配置逻辑在实例化时就已经执行完成,后置修改instance属性不会回溯更新已经生成的字段配置。所有动态过滤需要的参数,都要在实例化表单时通过kwargs显式传入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 15:31:57