Убедитесь, что тег используется в шаблоне только один раз

Я пишу собственный тег для использования в шаблонах django: {% my_custom_tag %}.

Используя каналы django, он расширяет некоторые функциональные возможности страницы. Но меня беспокоит, что пользователи могут случайно вставить этот тег дважды в шаблон, и это может создать некоторые проблемы, потому что каналы будут доставлять одну и ту же информацию дважды и т. д.

Есть ли относительно простой способ проверить, используется ли тег в шаблоне только один раз, и в противном случае вызвать ошибку?

1
0
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете управлять контекстом и установить определенный ключ (предпочтительно тот, который не используется другими приложениями) на True, а в противном случае вызвать исключение. Например:

@register.simple_tag(takes_context=True)
def my_custom_tag(context):
    if '__some_weird_name__for_my_custom_tag' in context:
        raise Exception('my_custom_tag is already used')
    context['__some_weird_name__for_my_custom_tag'] = True
    # ...
    # do other logic
    pass

Конечно, условием является то, что вы не передаете контент с этим именем изначально в контекст.

Более того, если вы будете выполнять несколько render(..) в представлении, они обычно будут иметь отдельный контекст, но это, вероятно, желательно.

Обратите внимание, что ошибка возникает в время выполнения. Таким образом, проактивно не обнаруживает шаблоны, в которых это происходит, но мы получим ошибку, если это произойдет.

Мне нравится твой подход. Но у меня вопрос: та же функциональность доступна в теге {% extends%} в django: когда мы используем его более одного раза, возникает ошибка. Вот как они это сделали (просто скопируйте из исходного кода django): gist.github.com/chapkovski/5c7c34667882c3a159cfdc0aa515a4a2 Разве не лучше?

Philipp Chapkovski 10.08.2018 15:09

@PhilippChapkovski: ну, это не гарантирует, что это произойдет более двух раз: это гарантирует, что это не произойдет более одного раза на файл. Это что-то другое. Например, файл может быть {% extends otherfile.html %}, а otherfile.html может содержать дополнительный {% extends andanotherfile.html %}. Таким образом, вы «разбираете» абстрактное синтаксическое дерево файла.

Willem Van Onsem 10.08.2018 15:11

@PhilippChapkovski: см., Например, здесь: gist.github.com/joar/4f1aa693c9a29c0d1deb

Willem Van Onsem 10.08.2018 15:15

ах, я вижу, вы совершенно правы. Он также может содержать {% include%}, указывающий на файл с использованием {% my_custom_tag%}, и ваш подход также блокирует это. Хорошо, спасибо!!

Philipp Chapkovski 10.08.2018 15:15

Другие вопросы по теме