Search code examples
djangodjango-viewsdjango-templatesdjango-urls

Reusing queryset within a view that is called multiple times?


I have a view that is part of a page, I am using HTMX to update this view multiple times (each time is a new question, the user answers, then the next question is shown). The rest of the page does NOT reload.

My issue is, every time the view is updated to ask a new question, it hits the database to get all the questions. Is there any way to pass all the questions on to all subsequent views, without hitting the database every time? I tried to pass it to the template, then back to the view, but that seems like a sup-optimal solution, and I could not get it to work anyway (it did not send objects back to the view, just characters).

Here is the view.py:

@login_required
def question(request):
   questions = Question.objects.all()
if request.method == 'POST':
    ## do stuff with the users answer, get next question
    answer = (request.POST.get("answer"))
    return render(request, 'interview/question.html', context)

Here is the question.html:

<form method="post">
            {% csrf_token %}
            <input class="input" name="answer" type="text"></input><br><br>
            <input type="submit" value="Next Question" class="is-fullwidth pg-button-secondary"
            hx-post="{% url 'interview:next_question' %}" 
            hx-target="#questionDiv" 
            hx-include="[name='answer']"
            hx-vals = '{"questionNumber": "{{ question.question_number}}", "questions": "{{ questions}}"}'
            hx-swap="innerHTML"></input>
          </form>

Solution

  • If you are not willing to manage the extra complexity of managing a cache store, you can use Memcached.


    If you don’t want to use that either then just do this:

    @login_required
    def question(request):
        if not hasattr(question, 'questions'):
            question.questions = Question.objects.all()
        •••
    

    The query is saved as a static variable of the function question and it is the same upon successive function calls. The database doesn’t get hit after the first hit. To use the QuerySet, you can access it like so:

    _usage = question.questions