'How to cache query data per request

I have a decorator that fetches some data from DB and modifies response context data. This decorator is applied to several views, the problem is that every time the decorator function is being executed it makes the DB query again. I would like to cache the result of a DB only per request, on page refresh/new request I would like to fetch data again.

views.py

def set_data():

  def wrap(request):
   # fetching data from db
   data = get_some_data_from_db()
   response = view(request)
   response.context_data["data"] = data
   return response.render()

 return wrap


@set_data
def view1(request):
  context = {...}
  return TemplateResponse(request, "template1.httml", context)

@set_data
def view2(request):
  context = {...}
  return TemplateResponse(request, "template2.httml", context)

I've tried to use django-request-cache library, but this doesn't solve this problem.

ANy idea how can i achieve it?



Solution 1:[1]

Here's my suggestion using functools.lru_cache:

from functools import lru_cache

# definition of get_some_data_from_db
@lru_cache(max_size=None)
def get_some_data_from_db():
    # get from db code here...

def view1(request):
    context = {
        # returns cached result
        'data': get_some_data_from_db()  
    }
    # ...
    return TemplateResponse(request, "template1.html", context)


def view2(request):
    context = {
        # returns cached result
        'data': get_some_data_from_db()  
    }
    # ...
    return TemplateResponse(request, "template2.html", context)

def view_that_handles_form_submit(request):
    if request.method == 'POST':
       form = MyFormClass(request.POST)
       if form.is_valid():
           # save input
           form.save()
           # clear the cache 
           get_some_data_from_db.cache_clear()
           context = {
              'form': form,
              'data': get_some_data_from_db(),  # fills cache with new result
           }
    return TemplateResponse(request, "form_template.html", context)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1