Django跳转device_port_selected视图报错缺少必填pk参数如何解决
Django视图参数传递故障修复方案
报错device_port_selected() missing 1 required positional argument: 'pk'有三个核心原因:
- 路由未配置
pk参数的接收规则 - 重定向调用时未传递
pk参数,且错误向重定向方法传递上下文参数 - 目标视图存在多处未定义变量,没有根据传入的
pk重新查询业务数据
步骤1:修改urls.py路由配置
给device-port-selected路由增加pk参数匹配规则,修改后代码:
urlpatterns = [ path('', views.home, name='interface-home'), path('device/', DeviceListView.as_view(), name='interface-device'), path('device_edit/<int:pk>/', views.device_edit, name='device-edit'), path('device_delete/<int:pk>/', views.device_delete, name = 'device-delete'), path('device_add/', views.device_add, name='device-add'), path('device/port/', views.device_port, name='device-port'), # 新增<int:pk>参数捕获规则 path('device/port/selected/<int:pk>/', views.device_port_selected, name='device-port-selected'), path('device/routeport/', views.device_routeport, name='device-routeport'), path('interface/', views.interface_list, name='interface-list') ]
步骤2:修正device_port视图的重定向逻辑
注意:redirect是触发浏览器发起新的GET请求,无法直接传递上下文字典,相关业务数据需要在目标视图根据pk重新查询,或者存入session临时存储。修改后代码:
def device_port(request): devices = Device.objects.all() if request.method == "POST": selected=request.POST.get('device') # 用命名路由传递pk参数,避免硬写URL return redirect('device-port-selected', pk=selected) return render(request, 'interface/device_port.html',{'devices':devices})
步骤3:修正device_port_selected视图的变量问题
在视图开头根据传入的pk查询所有需要的业务数据,解决变量未定义问题,修改后代码:
def device_port_selected(request, pk): # 先根据传入的pk查询基础业务数据 devices = Device.objects.get(pk=pk) selected = pk tablename = 'dev_interface_'+str(pk) cursor=connection.cursor() cursor.execute(f"SELECT interface FROM {tablename} WHERE id >=2") righttable = cursor.fetchall() if request.method == "POST": job = JobForm(request.POST) device = devices.hostname print(devices) #job.associateddevice = devices.hostname try: selection=request.POST.get('portrange') except: selection = "" messages.warning(request, "Please select the ports") print(selection) #job.associatedinterface = selection return render(request, f'interface/device/port/selected/{device}.html',{'devices':devices, 'righttable':righttable} ) return render(request, 'interface/device_port_selected.html',{'devices':devices, 'selected': selected, 'righttable':righttable} )
注意:直接拼接SQL语句存在SQL注入风险,建议增加参数合法性校验,或者改用Django ORM操作数据库
可选补充:确保前端隐藏域赋值生效
你代码中下拉框绑定了getSelectValue()方法,需要确保该方法将选中的设备id赋值给隐藏的name="device"输入框,否则request.POST.get('device')会拿到空值,示例JS代码:
function getSelectValue() { const selectVal = document.getElementById('list').value; document.getElementById('txtvalues').value = selectVal; }
内容的提问来源于stack exchange,提问作者L.Calvin
相关产品推荐
相关产品推荐

