【问题标题】:Saving result of function in session results in TypeError object not JSON serializable在会话中保存函数结果导致 TypeError 对象不可 JSON 序列化
【发布时间】:2019-09-28 10:38:24
【问题描述】:

我在 services.py 文件中有一个函数:

def someFunction():
 if choice == 'Choice1'
  result1 = Choice1.objects.all.order_by('?')[0]
  result2 = Choice1.objects.all.order_by('?')[0]
  result3 = Choice1.objects.all.order_by('?')[0]
 elif choice == 'Choice2'
  result1 = Choice2.objects.all.order_by('?')[0]
  result2 = Choice2.objects.all.order_by('?')[0]
  result3 = Choice2.objects.all.order_by('?')[0]

  result = [result1, result2, result3]

 return result

我像这样将它传递给视图:

def template(request):
  request.session['result'] = someFunction() #save result to session


  result = request.session['result'] #retrieve saved result from session


  context = {
      'resulting': list(result)
  }
  return render(request, 'project/template.html', context)

然后传递给模板等

但是这会导致“TypeError at /template object type of results is not JSON Serializable.”

如果我不尝试将函数结果保存到会话中,一切正常。我不确定自己做错了什么,或者是否有更好的方法可以将函数的结果保存到会话中。

感谢任何帮助。

【问题讨论】:

    标签: python django session


    【解决方案1】:

    问题不是“保存函数的结果”,而是“保存模型实例列表”。这些不能直接序列化。

    最好的办法是只保存 ID:

    result = someFunction()
    request.session['result'] = [item.id for item in result]
    

    然后,当您需要取回它们时,从 ID 中获取项目,或者单独以尊重排序:

    result = [Choice1.objects.get(id) for id in request.session.get('result', [])]
    

    或一次性获取它们并按您的列表排序:

    ids = request.session.get('result', [])
    items = Choice1.objects.filter(id__in=ids)
    result = sorted(items, key=lambda item: ids.index(item.id))
    

    编辑

    你需要检查会话是否已经包含一个结果,如果没有得到一个新的。

    result_ids = request.session.get('result')
    if result_ids:
        # if we have IDs, get the matching items and use them
        items = Choice1.objects.filter(id__in=result_ids)
        result = sorted(items, key=lambda item: ids.index(item.id))
    else:
        # otherwise, get new ones and store them
        result = someFunction()
        request.session['result'] = [item.id for item in result]
    
    return render(request, 'project/template.html', {'resulting': result})
    

    【讨论】:

    • 感谢您的回复 - request.session['result'] = [item.id for item in result] 抛出错误 - 'int' 对象没有属性 'id'
    • 不,它与您上面显示的代码无关。如果你的函数返回 ID,那么你一开始就不会得到原始的 TypeError。
    • 哦,对不起,我有一个错误!感谢您的帮助,我不再遇到错误,但传递给视图的函数结果在每次页面刷新时仍然刷新:(我已将您标记为正确,因为您回答了我的问题。再次感谢您。
    • 我不太明白你的意思。如果您上面给出的代码是您正在使用的代码,那么它当然会在每次请求时发生变化,因为您总是调用 someFunction 并且每次都存储新值。也许您的意思是检查会话是否已经有结果,如果有,请使用它而不是调用someFunction
    • 嗨丹尼尔,是的,这正是我想做的,你能建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 2017-09-23
    • 2019-08-06
    • 1970-01-01
    • 2018-12-31
    • 2019-10-27
    相关资源
    最近更新 更多