Используйте сеансы Django для просмотра, а не для каждого пользователя

Я смущен!

Я пытаюсь использовать систему кэширования Django для хранения некоторых данных, чтобы они были доступны через GET/PUT основного представления, а также несколько потенциальных представлений AJAX, когда пользователь взаимодействует со страницей.

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

Я думал, что для этого можно использовать session_key. Но при использовании сеансов на основе кеша этот ключ кажется одинаковым для всех экземпляров.

Вот код:

def my_view(request):
  my_session_id = request.session.session_key
  my_complex_thing_key = u"my_complex_thing_%s" % my_session_id
  my_complex_thing = cache.get(my_complex_thing_key)
  if not my_complex_thing:
    my_complex_thing = my_complex_function()  # this is very expensive, I want to avoid having to do it repeatedly in AJAX calls
    cache.set(my_complex_thing_key, my_complex_thing)
  if request.method == "GET":
    my_form = MyFormFactory(my_complex_thing)
  elif request.method == "POST":
    my_form = MyFormFactory(request.POST, my_complex_thing)
    if my_form.is_valid():
      my_form.save()
  return render_to_response('my_template.html', {"form": my_form}, context_instance=RequestContext(request))

Проблема в том, что my_complex_thing_key будет одинаковым каждый раз, когда один и тот же пользователь запускает это представление. Я хотел бы, чтобы он менялся каждый раз, когда пользователь делает новый запрос GET.

Внезапно, я думаю, я мог бы сгенерировать руководство в GET, а затем отслеживать его (передавая его в качестве аргумента шаблону?) И сбрасывать его только после успешного сохранения в POST.

У кого-нибудь есть лучшие идеи?

Спасибо


person trubliphone    schedule 05.03.2015    source источник
comment
Этот вопрос связан с stackoverflow.com/questions/17103280/, что означает, что это невозможно сделать с помощью сеансов.   -  person trubliphone    schedule 06.03.2015


Ответы (1)


Отвечая на мой собственный вопрос...

def get_key_from_request(request):
  if not request.is_ajax():
    if request.method == "GET":
        # a normal GET resets the key
        key = str(uuid4())
    else:
        # a normal POST should have the key in the datadict
        key = request.POST["key"]
  else:
    if request.method == "GET":
        # an AJAX GET should have passed the key as a parameter
        key = request.GET["key"]
    else:
        # an AJAX POST should have the key in the datadict
        key = request.POST["key"]
  return key

затем в представлении:

def my_view(request):
  my_complex_thing_key = u"my_complex_thing_%s" % get_key_from_request(request)
  my_complex_thing = cache.get(my_complex_thing_key)
  if not my_complex_thing:
    my_complex_thing = my_complex_function()
    cache.set(my_complex_thing_key, my_complex_thing)
  if request.method == "GET":
    my_form = MyFormFactory(my_complex_thing)
  elif request.method == "POST":
    my_form = MyFormFactory(request.POST, my_complex_thing)
    if my_form.is_valid():
      my_form.save()
  return render_to_response('my_template.html', {"form": my_form, "key": my_complex_thing_key}, context_instance=RequestContext(request))

Затем в шаблоне:

<form method="POST" action="">
  <input class="hidden" type="text" id="_key" name="key" value="{{ key }}"/>
  ...
</form>

Теперь этот ввод будет доступен в request.POST для основного представления, и я могу добавить его в AJAX GET/POST по мере необходимости.

person trubliphone    schedule 05.03.2015