Мне было бы любопытно, если бы вы могли сделать это, используя вместо этого патчи / декорирование обезьяны get_template. Я думаю, что вы можете, хотя вы должны найти все шаблоны загрузки
функции (у меня есть два в моем примере ниже).
Я использовал wrapt , когда заметил, что он выходит за рамки просто loader.get_template, но, похоже, уловка просто отлично. Конечно, держите эти 50000 км подальше от прод, но ...
Теперь следует также отметить, что я управляю этим с помощью юнит-тестов и тестов носа, поэтому, если у вас есть полный охват ветвей вашего шаблона с использованием кода Python, вы сможете получить большинство шаблонов (при условии, что я этого не делал) не пропустите ни одной функции типа get_template).
in settings.py
Это "мозги" для патча get_template & co.
import wrapt
import django.template.loader
import django.template.engine
def wrapper(wrapped, instance, args, kwargs):
#concatenate the args vector into a string.
# print "\n\n\n\n%s\nI am a wrapper \nusage:%s\n%s\n\n\n\n\n" % ("*"*80, usage, "*"*80)
try:
return wrapped(*args, **kwargs)
finally:
usage = ",".join([unicode(arg) for arg in args if arg])
track_usage(usage)
#you have to wrap whatever is loading templates...
#imported django module + class/method/function path of what needs to be
#wrapped within that module. comment those 2 lines out and you are back to
#normal
wrapt.wrap_function_wrapper(django.template.loader, 'get_template', wrapper)
wrapt.wrap_function_wrapper(django.template.engine, 'Engine.find_template', wrapper)
См. safe-apply-monkey-patches-in-python для более подробной информации о оболочке. На самом деле легче использовать, чем понимать документы, декораторы делают мой мозг болит.
Кроме того, чтобы отследить, какие функции django выполняли фактические загрузки, я специально ввел имена некоторых шаблонов в коде и в шаблонах, запустил на нем модульные тесты и просмотрел трассировки стека на предмет отсутствия шаблонных исключений.
Это моя довольно плохо написанная функция, которая добавляет набор и помещает его в
вывод JSON ....
def track_usage(usage):
fnp_usage = "./usage.json"
try:
with open(fnp_usage, "r") as fi:
data = fi.read()
#read the set of used templates from the json file
j_data = json.loads(data)
s_used_file = set(j_data.get("li_used"))
except (IOError,),e:
s_used_file = set()
j_data = dict()
s_used_file.add(usage)
#convert the set back to a list for json compatibility
j_data["li_used"] = list(s_used_file)
with open(fnp_usage, "w") as fo:
json.dump(j_data, fo)
и вывод (со скриптом для его форматирования):
import sys
import json
fnp_usage = sys.argv[1]
with open(fnp_usage, "r") as fi:
data = fi.read()
#read the set of used templates from the json file
j_data = json.loads(data)
li_used_file = j_data.get("li_used")
li_used_file.sort()
print "\n\nused templates:"
for t in li_used_file:
print(t)
Из-за переноса двух функций, описанных выше, кажется, что он уловил extends,% includes и direct get_templates, а также шаблоны типа списка, которые использовались представлениями на основе классов. Он даже поймал мои динамически сгенерированные шаблоны, которые даже не находятся в файловой системе, но загружаются с помощью специального загрузчика.
used templates:
bootstrap/display_form.html
bootstrap/errors.html
bootstrap/field.html
bootstrap/layout/baseinput.html
bootstrap/layout/checkboxselectmultiple.html
bootstrap/layout/field_errors.html
bootstrap/layout/field_errors_block.html
bootstrap/layout/help_text.html
bootstrap/layout/help_text_and_errors.html
bootstrap/layout/radioselect.html
bootstrap/whole_uni_form.html
django_tables2/table.html
dynamic_template:db:testdb:name:pssecurity/directive.PrimaryDetails.json
uni_form/layout/div.html
uni_form/layout/fieldset.html
websec/__base.html
websec/__full12.html
websec/__l_right_sidebar.html
websec/bootstrapped_home.html
websec/changedb.html
websec/login.html
websec/requirejs_config.html
websec/topnav.html
websec/user_msg.html