pythondjangoweb-applicationsajax-polling

Can you pause a Django view execution until a condition is met?


I have a request to an external API within a view which returns two separate solutions. What I would like to achieve is a pause on the execution (so the results are in memory) and, once the user on the front-end decides which solution to save, the execution continues and the results they chose are saved.

What I’ve initially tried is something like this:

def result_user_wants(request):
    request.session[‘user_wants_result’]
    return JsonResponse({‘result_user_wants’: 1})


def view_to_pause(request):

    while ‘user_wants_result’ not in request.session.keys():
        sleep(1)

    code_that_saves_result()

Whatever the user decides on the front end is passed to the results_user_wants view and modifies the session data. What I’m then hoping is that the while loop in view_to_pause is paused until the key exists. This unfortunately doesn’t work, I think because the request data hasn’t been refreshed due to the pause.

My only other thought is to save both results sets in the database and when the user chooses, the other result set is deleted. Appreciate any other thoughts!


Solution

  • I don't think you want to pause execution of a view. It looks like your flow is:

    1. User initiates this process.
    2. Check API and fetch two solutions.
    3. Present both solutions to the user.
    4. User chooses solution.
    5. Respond with success message.

    This is two separate requests, possibly to the same form view:

    1. Request one:
      1. GET request to solution list URL
      2. fetch solutions from API
      3. respond with solution choices
    2. Request two:
      1. POST to solution create URL
      2. respond with success message

    The URLs could be the same one. Storing something in the session seems sensible. Your view might look like:

    def solution_form(request):
        if request.method == "post":
            solutions = request.session.get("solutions", {})
            form = SolutionChoiceForm(request.POST, solution_ids=solutions.keys())
            if form.is_valid():
                solution_id = form.cleaned_data["solution"]
                try:
                    solution = solutions[solution_id]
                except IndexError:
                    continue
                else:
                    request.session.pop("solutions")
                    ...  # save the solution
        else:
            # It's a GET request, so we fetch solutions from the API,
            # imagine they look like:
            solutions = {
               1: "foo",
               2: "bar",
            }
            request.session[solutions] = solutions
            form = SolutionChoiceForm(solution_ids=solutions.keys())
        return response(request, "solution_list.html", context={"form": form})
    

    I'm skipping anything here which makes the form dynamic, but it could include parsing of an argument called solution_ids maybe, which would then set the choices attribute of a solution field.