Fully-Faltoo blog by Pratyush

Bio Twitter Screener

10th March 2021

Lazy functions in Django [Functional programming]

I love to write functions instead of classes. However, Django does not allow us to call functions inside templates. Sometimes we want to postpone the function calls in templates because they might be expensive. Thus we might want to call them inside the template’s cache fragment or inside an `if` statement. My way around them is to use a `lazy_cache` function to postpone and cache a function's result. Thus the whole usage is something like this: ```python import datetime as dt from utilities.functional import lazy_cached def expensive_computation(result_date, page_number=1): # do some expensive stuff return results def latest_results(request): result_date = dt.datetime.today() page_number = request.GET.get('page') results = lazy_cached( expensive_computation, result_date, page_number=request.GET, ) return render( request, "latest-results.html", { "results": results, "page_number": page_number, }, ) ``` In templates we can now do: ```html {% load cache %} {% block content %} {% cache 30000 results_page page_number %} {% for result in results %}

{ { result.name }}
{% endfor %} {% endcache %} ``` My recipe for lazy_cached function is: ```python def lazy_cached(func, *args, **kwargs): state = {"value": None, "realized?": False} def wrap(): if state["realized?"]: return state["value"] state["value"] = func(*args, **kwargs) state["realized?"] = True return state["value"] return wrap ```