Сохранение результата функции в сеансе приводит к тому, что объект TypeError не сериализуем в формате JSON - PullRequest
0 голосов
/ 10 мая 2019

У меня есть функция в файле 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 в / тип объекта шаблона не является сериализуемым JSON.'

Если я не пытаюсь сохранить результаты функции в сеансе, все работает нормально. Я не уверен, что делаю неправильно, или есть ли лучший способ добиться сохранения результата функции в сеансе.

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 10 мая 2019

Проблема не в «сохранении результатов функции», а в «сохранении списка экземпляров модели». Они напрямую не сериализуются.

Лучше всего сохранить только идентификаторы:

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

затем, когда вам нужно вернуть их, извлеките элементы из идентификаторов, либо по отдельности, чтобы соблюсти порядок:

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})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...