Страницы

Поиск по вопросам

Показаны сообщения с ярлыком jinja2. Показать все сообщения
Показаны сообщения с ярлыком jinja2. Показать все сообщения

воскресенье, 15 марта 2020 г.

Вывод древовидной структуры в шаблоне jinja2

#python #django #python_2x #jinja2


Имеется список словарей вида:

[
 {'comment_id': 9, 'level': 1, 'path': [9]},
     {'comment_id': 11, 'level': 2, 'path': [9, 11]},
 {'comment_id': 12, 'level': 1, 'path': [12]},
     {'comment_id': 13, 'level': 2, 'path': [12, 13]},
     {'comment_id': 14, 'level': 2, 'path': [12, 14]},
         {'comment_id': 15, 'level': 3, 'path': [12, 14, 15]},
             {'comment_id': 16, 'level': 4, 'path': [12, 14, 15, 16]}
]


comment_id - уникальный идентификатор комментария, level - уровень вложенности, path
- список-путь к родителю, где каждый элемент является идентификатором comment_id.

Вывод на стринце должен быть такой:

comment9
    comment11
comment12
    comment13
    comment14
        comment15
            comment16


Возможно ли повторить подобную вложенность в шаблоне jinja2 располагая имеющимися
данными?
    


Ответы

Ответ 1



Пример из документации http://jinja.pocoo.org/docs/dev/templates/
    {%- for item in sitemap recursive %}
  • {{ item.title }} {%- if item.children -%} {%- endif %}
  • {%- endfor %}


воскресенье, 9 февраля 2020 г.

Счетчик в jinjja2

#python #jinja2


Не работает счетчик i. Данные заполняются, но переменная не инкрементируется. Значение
счетчика i всегда 1. Как поправить?

{% set i = 0 %}
{% for class in classes %}
        
  • {{ class }}
  • {% set i = i+1 %}
  • {{ i }}
  • {% if i == 4 %}
    {% endif %} {% endfor %}


    Ответы

    Ответ 1



    Внутри циклов можно использовать {{ loop.index }}: {% for class in classes %}
  • {{ class }}
  • {{ loop.index }}
  • {% if loop.index == 4 %}
    {% endif %} {% endfor %} PS. странно, у меня {% set %} тоже не работает, возможно эта бага: https://github.com/pallets/jinja/issues/659

    Ответ 2



    Решение этой проблемы описано в документации: {% set ns = namespace(counter=false) %} {% for class in classes %}
  • {{ class }}
  • {% set ns.counter = ns.counter+1 %}
  • {{ ns.counter }}
  • {% if ns.counter == 4 %}
    {% endif %} {% endfor %} As of version 2.10 more complex use cases can be handled using namespace objects which allow propagating of changes across scopes Note hat the obj.attr notation in the set tag is only allowed for namespace objects; attempting to assign an attribute on any other object will raise an exception. New in version 2.10: Added support for namespace objects Документация: http://jinja.pocoo.org/docs/2.10/templates/ CTRL+F -> Scoping Behavior.

    пятница, 24 января 2020 г.

    Аналог grep -v для ansible

    #python #регулярные_выражения #администрирование #ansible #jinja2

    
    Нужно получить всех когда-либо входивших пользователей на винде. В списке не должно
    быть папки Public.
    
    Такая конструкция не работает:
    
    - name: TEST find 4 win
      block:
        - win_find:
            paths: C:\Users\
            file_type: directory
            excludes: Public
          register: win_find_out
        - debug:
            msg: "{{ win_find_out.files }}"
    
    
    Есть ещё параметр patterns, но !Public, ?!Public или not (Public) не работают - выхлоп
    вообще пропадает.
    
    ansible 2.7.5
        
    


    Ответы

    Ответ 1



    Вы можете использовать такое регулярное выражение: ^(?!.*Public) См. демо регулярного выражения онлайн. Подробности ^ - начало строки (?!.*Public) - исключающий блок предварительного просмотра вперёд, который не вернёт совпадения, если сразу после текущей позиции имеется .* - 0 и более символов, отличных от символа перевода на новую строку Public - строка Public Если в строке могут быть символы переноса строки, добавьте (?s) в начало: (?s)^(?!.*Public)

    понедельник, 6 января 2020 г.

    Кнопка вызова функции python flask

    #python #веб_программирование #flask #jinja2

    
    Как с помощью библиотеки jinja2 при нажатии кнопки можно вызвать функцию в python,
    передав параметр id этой кнопки? Долго просматривал документацию и искал похожие вопросы,
    но так и не нашел ничего схожего. 
    
    Имеется следующие части кода:
    
    main.py
    
    def json_load(num):
    with open('db/pub_keys.json', 'r', encoding='utf-8') as file:
        file_dumps = json.load(file)
        for elem in file_dumps:
            if elem.get('id') == num:
                print(f'\nPK user with num {num}:')
                print(elem.get('meta').get('pub_key'))
    
    
    file.html
    
    
    
    
    Нужно, чтобы при нажатии на кнопку вызывалась функция json_load() с передачей в ней
    аргумента id нажатой кнопки. пытался использовать {{ }} внутри onclick и action, но
    это не помогло.
    
    Возможно ли реализовать это по средствам jinja2?
        
    


    Ответы

    Ответ 1



    Jinja2 – это всего лишь библиотека для упрощения генерации HTML страниц. А нужная Вам задача решается средствами простых HTTP запросов, которые можно сделать и с помощью чистого HTML, и с помощью более управляемого JavaScript'a. 1.1. Чистый HTML + скрытые параметры В обоих случаях нужен обработчик запросов на стороне сервера. Однако чистым HTML'ем можно передать только обычный HTTP запрос, без JSON'а. На странице нужно сделать такие формы:
    А на серваке ловить эти действия и параметры: @app.route('/process_data/', methods=['POST']) def doit(): index = request.form['index'] # ... обработать данные ... 1.2. Чистый HTML + параметры в адресе Фласк позволяет легко обрабатывать аргументы как часть пути:
    А на серваке так: @app.route('/process_data//', methods=['POST']) def doit(index): # ... обработать данные ... 1.3. Чистый HTML + JSON форма Форме можно поставить тип формата, тогда поддерживающие этот JSON браузеры отправят данные в нужном формате, а не поддерживающие вернутся к классическому form url encoded:
    Больше подробностей и реально интересных примеров с формой JSON доступны внизу по ссылке №5. На сервере ловить JSON тоже достаточно легко: @app.route('/process_data/', methods=['POST']) def doit(): data = request.get_json(silent=True) index = data["index"] # ... обработать данные ... 2. HTML + JavaScript Очевидно, что способы выше предполагают много повторяющегося HTML кода, что явно не удобно, особенно если захочется что-то поменять. JavaScript может значительно упростить код предоставив большую гибкость, а также позволит не перезагружать страницу при отправке данных: Теперь конкретный формат запроса будет определён лишь в одном месте. В самом скрипте можно поступить по-разному. 2.1. Вариант для сервера из 1.1, где данные передаём HTTP аргументами: function process(index) { $.post("/process_data/", {'index': index}, function (data, status) { alert("Data: " + data + "\nStatus: " + status); }); } 2.2. Вариант для сервера из 1.2, где данные передаём как часть пути: function process(index) { $.post("/process_data/" + index + "/", {}, function (data, status) { alert("Data: " + data + "\nStatus: " + status); }); } 2.3. И, наконец, вариант для сервера из 1.3, c JSON на борту: function process(index) { $.ajax({ url: "/process_data/", type: "post", dataType: "json", success: function (data) { alert(data); }, data: {"index": index} }); } Для простоты здесь используется JS в связке с библиотекой jQuery. Полезные и использованные ссылки Документация Flask (в которой, вообще-то, есть всё необходимое) jQuery AJAX get and post Пример AJAX с JSON Про использование JSON во Flask'e Отправка JSON формы чистым HTML

    среда, 9 января 2019 г.

    Кнопка вызова функции python flask

    Как с помощью библиотеки jinja2 при нажатии кнопки можно вызвать функцию в python, передав параметр id этой кнопки? Долго просматривал документацию и искал похожие вопросы, но так и не нашел ничего схожего.
    Имеется следующие части кода:
    main.py
    def json_load(num): with open('db/pub_keys.json', 'r', encoding='utf-8') as file: file_dumps = json.load(file) for elem in file_dumps: if elem.get('id') == num: print(f'
    PK user with num {num}:') print(elem.get('meta').get('pub_key'))
    file.html

    Нужно, чтобы при нажатии на кнопку вызывалась функция json_load() с передачей в ней аргумента id нажатой кнопки. пытался использовать {{ }} внутри onclick и action, но это не помогло.
    Возможно ли реализовать это по средствам jinja2?


    Ответ

    Jinja2 – это всего лишь библиотека для упрощения генерации HTML страниц. А нужная Вам задача решается средствами простых HTTP запросов, которые можно сделать и с помощью чистого HTML, и с помощью более управляемого JavaScript'a.

    1.1. Чистый HTML + скрытые параметры
    В обоих случаях нужен обработчик запросов на стороне сервера. Однако чистым HTML'ем можно передать только обычный HTTP запрос, без JSON'а. На странице нужно сделать такие формы:



    А на серваке ловить эти действия и параметры:
    @app.route('/process_data/', methods=['POST']) def doit(): index = request.form['index'] # ... обработать данные ...

    1.2. Чистый HTML + параметры в адресе
    Фласк позволяет легко обрабатывать аргументы как часть пути:


    А на серваке так:
    @app.route('/process_data//', methods=['POST']) def doit(index): # ... обработать данные ...

    1.3. Чистый HTML + JSON форма
    Форме можно поставить тип формата, тогда поддерживающие этот JSON браузеры отправят данные в нужном формате, а не поддерживающие вернутся к классическому form url encoded


    Больше подробностей и реально интересных примеров с формой JSON доступны внизу по ссылке №5.
    На сервере ловить JSON тоже достаточно легко:
    @app.route('/process_data/', methods=['POST']) def doit(): data = request.get_json(silent=True) index = data["index"] # ... обработать данные ...

    2. HTML + JavaScript
    Очевидно, что способы выше предполагают много повторяющегося HTML кода, что явно не удобно, особенно если захочется что-то поменять. JavaScript может значительно упростить код предоставив большую гибкость, а также позволит не перезагружать страницу при отправке данных:

    Теперь конкретный формат запроса будет определён лишь в одном месте. В самом скрипте можно поступить по-разному.
    2.1. Вариант для сервера из 1.1, где данные передаём HTTP аргументами:
    function process(index) { $.post("/process_data/", {'index': index}, function (data, status) { alert("Data: " + data + "
    Status: " + status); }); }
    2.2. Вариант для сервера из 1.2, где данные передаём как часть пути:
    function process(index) { $.post("/process_data/" + index + "/", {}, function (data, status) { alert("Data: " + data + "
    Status: " + status); }); }
    2.3. И, наконец, вариант для сервера из 1.3, c JSON на борту:
    function process(index) { $.ajax({ url: "/process_data/", type: "post", dataType: "json", success: function (data) { alert(data); }, data: {"index": index} }); }
    Для простоты здесь используется JS в связке с библиотекой jQuery.

    Полезные и использованные ссылки
    Документация Flask (в которой, вообще-то, есть всё необходимое) jQuery AJAX get and post Пример AJAX с JSON Про использование JSON во Flask'e Отправка JSON формы чистым HTML