Django应用ForeignKey无法JSON序列化问题求助
解决"<Shipment: 219002> is not JSON serializable"错误
这个错误的根源非常明确:你试图将包含Shipment模型实例的数据存入Django的session,但session存储要求数据必须是可JSON序列化的,而Django模型对象本身无法直接被JSON序列化。
为什么会出现这个问题?
从你的代码和报错回溯能清晰定位原因:
- 在
preview分支中,你直接把form.cleaned_data存入了request.session['data'] - 你的
PackingListForm包含Reference_Number字段,它是关联Shipment的ForeignKey - Django ModelForm的
cleaned_data中,ForeignKey字段对应的是完整的模型实例(比如<Shipment: 219002>),而不是简单的ID或字符串 - 当Django尝试保存session时,会自动序列化session数据到JSON,遇到模型实例就会抛出序列化失败的错误
解决方案:只存可序列化的数据到session
你需要修改代码,将cleaned_data中的模型实例替换为可序列化的类型(比如主键ID),只把必要的、能被JSON序列化的数据存入session。
修改views.py中的preview分支:
if 'preview' in request.POST: # 复制cleaned_data,避免修改原数据 serialized_data = form.cleaned_data.copy() # 将Shipment实例替换为它的主键ID if serialized_data.get('Reference_Number'): serialized_data['Reference_Number'] = serialized_data['Reference_Number'].pk # 存入session request.session['data'] = serialized_data return redirect('myview')
如果你在后续的myview中需要使用这个Shipment对象:
在myview里通过ID重新查询即可:
def myview(request): session_data = request.session.get('data', {}) # 恢复Shipment对象 shipment_id = session_data.get('Reference_Number') if shipment_id: shipment = Shipment.objects.get(pk=shipment_id) session_data['Reference_Number'] = shipment # 其他逻辑... return render(request, 'preview.html', {'data': session_data})
同样处理save分支中的session操作:
你在save分支里也有request.session['data'] = form.cleaned_data,这里同样会触发序列化错误,需要一并修改:
elif 'save' in request.POST: form.save() # 序列化数据存入session serialized_data = form.cleaned_data.copy() if serialized_data.get('Reference_Number'): serialized_data['Reference_Number'] = serialized_data['Reference_Number'].pk request.session['data'] = serialized_data # 后续PDF生成逻辑...
额外提示
- 永远不要将Django模型实例直接存入session、cookie或其他需要序列化的存储中
- 如果需要在请求间传递模型相关数据,优先传递模型的主键ID,在需要时再查询实例
- 如果你需要传递更复杂的结构化数据,可以考虑使用Django的
serializers模块将模型实例序列化为JSON格式字符串,再存入session
内容的提问来源于stack exchange,提问作者GXM100
相关产品推荐
相关产品推荐

