Если вы передадите вызываемый объект в контекст шаблона, Django оценит его, когда он будет использован в шаблоне.Это обеспечивает один простой способ сделать лень - просто передать вызываемые объекты:
def my_context_processor(request):
def complicated_query():
do_stuff()
return result
return {'result': complicated_query}
Проблема в том, что он не запоминает вызов - если вы используете его несколько раз, complicated_query
вызывается несколько раз.
Исправление состоит в том, чтобы использовать что-то вроде SimpleLazyObject
, как в другом ответе, или использовать что-то вроде этого декоратора памятки:
def memoize_nullary(f):
"""
Memoizes a function that takes no arguments.
"""
def func():
if not hasattr(func, 'retval'):
func.retval = f()
return func.retval
return func
def my_context_processor(request):
@memoize_nullary
def complicated_query():
do_stuff()
return result
return {'result': complicated_query}
Или, если функция уже существует, вы бысделайте это так:
from somewhere import complicated_query
def my_context_processor(request):
return {'result': memoize_nullary(complicated_query)}
Я бы предпочел этот метод, а не SimpleLazyObject
, поскольку последний может иногда вызывать странных ошибок .
(я был однимкоторый первоначально реализовал LazyObject
и SimpleLazyObject
и обнаружил для себя, что на любом артефакте кода, помеченном simple .)
, есть проклятие.