0

I am confused!

I am trying to use Django's caching system to store some data so that it is accessible throughout the GET/PUT of the main view as well as several potential AJAX views while the user is interacting w/ the page.

I thought that I would need a unique key for this data so that the user could be working on multiple instances at once (if, for example, they have the page open in multiple tabs).

I thought that the session_key could be used for this. But, when using cache-based sessions this key seems to be the same for all instances.

Here is some code:

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))

The issue is that my_complex_thing_key will be the same each time the same user runs this view. I would like for it to change every time the user makes a new GET request.

Off the top of my head, I guess I could generate a guid in the GET and then keep track of that (by passing it as an argument to the template?) and only resetting it after a successful save in the POST.

Does anybody have any better ideas?

Thanks

trubliphone
  • 4,132
  • 3
  • 42
  • 66
  • This question is related to http://stackoverflow.com/questions/17103280/different-values-of-a-django-session-variable-in-different-tabs which implies that it can't be done using sessions. – trubliphone Mar 05 '15 at 22:04

1 Answers1

0

Answering my own question...

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

then in the view:

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))

Then in the template:

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

Now that input will be available in the request.POST for the main view and I can add it to AJAX GET/POSTs as needed.

trubliphone
  • 4,132
  • 3
  • 42
  • 66