Особенности использования classy tags
7 сентября 2016 г. 8:20
Встретилась на моём пути маленькая проблемка совместного использования MultiValueArgument и MultiKeywordArgument:
class MyTag(Tag): name = 'my_tag' options = Options( MultiValueArgument('args'), MultiKeywordArgument('kwargs'), blocks=[('end_my_tag', 'nodelist')], ) def render_tag(self, context, args, kwargs, nodelist): # some logic ... return some_result # in template {% my_tag var_1 var_2 key_1=v_1 key=v_2 %}
Но это приводит к ошибке, так как: MultiValueArgument берёт все аргументы 'var_1 var_2 key_1=v_1 key=v_2' и пытается каждый аргумент распарсить в том числе и 'key_1=v_1' на что classy tags отвечает:
TemplateSyntaxError at /.../ Could not parse the remainder: '=v_1' from 'key_1=v_1'
Чтобы решить данную проблему, можно воспользоваться каким-нибудь стопором, например 'word_breakpoint':
class MyTag(Tag): name = 'my_tag' options = Options( MultiValueArgument('args'), 'word_breakpoint', MultiKeywordArgument('kwargs'), blocks=[('end_my_tag', 'nodelist')], ) def render_tag(self, context, args, kwargs, nodelist): # some logic ... return some_result # in template {% my_tag var_1 var_2 word_breakpoint key_1=v_1 key=v_2 %}
Но это же вынуждает нас использовать 'word_breakpoint'! Кстати, замечу, что этот стопор похож на стопор 'as' для реализации InclusionTag в самой Django или через classy tags.
Я начал искать решение не использовать стопор и благо нашёл в исходниках Django CMS https://github.com/divio/django-cms/blob/develop/cms/templatetags/cms_tags.py#L1038
Теперь можно заменить MultiValueArgument на MultiValueArgumentBeforeKeywordArgument, например так:
from cms.templatetags.cms_tags import MultiValueArgumentBeforeKeywordArgument class MyTag(Tag): name = 'my_tag' options = Options( MultiValueArgumentBeforeKeywordArgument('args'), MultiKeywordArgument('kwargs'), blocks=[('end_my_tag', 'nodelist')], ) def render_tag(self, context, args, kwargs, nodelist): # some logic ... return some_result # in template {% my_tag var_1 var_2 key_1=v_1 key=v_2 %}
И всё будет работать :)
Я писал разработчику classy tags с предложением модифицировать MultiValueArgument или добавить тотже MultiValueArgumentBeforeKeywordArgument в classy tags https://github.com/ojii/django-classy-tags/issues/39
Но в случае с модификацией MultiValueArgument, как пишет автор, могут возникать случаи, когда в значении аргумента используется знак '=', например:
{% my_tag "key_1=v_1" foo=bar %}
Я согласен с ним: хоть и редко, но такие случаи могут быть, например, при работе со строкой GET параметров.
А по поводу добавления нового класса наподобие MultiValueArgumentBeforeKeywordArgument в classy tags - разработчик этого не захотел. Он пишет, что приветствуется расширять какой-нибудь класс, находящийся в библиотеке classy tags. Собственно с MultiValueArgumentBeforeKeywordArgument так и вышло.
Может кому-нибудь другому удастся его убедить, но а пока используйте MultiValueArgumentBeforeKeywordArgument, который находится в Django CMS.
Похожие статьи:
Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.
Книга предназначается для широкого круга читателей и, по мнению автора, будет полезна специалистам отдела закупок и логистики, категорийным и финансовым менеджерам, менеджерам по продажам, аналитикам, руководителям и директорам, в компетенции которых принятие решений по управлению ассортиментом.
Комментарии: 0