Приложение django: как прочитать немного html в javascript

У меня есть приложение django, в котором есть проблема с дизайном, которую я хотел бы исправить: скрипт хочет ввести фрагмент html, содержащий теги django.

То, что мы имеем сейчас, работает, но имеет некоторые неприятные аспекты:

  • Сохраните скрипт в виде html-фрагмента, который является ничем иным, как скриптом: первая строка <script>, а последняя строка закрывает этот скрипт.
  • Страницы, использующие этот скрипт, импортируют его так же, как любой html-фрагмент.
  • Этот скрипт присваивает локальной переменной значение html, но в виде длинной строки, затем находит, где требуется html-бит, и вызывает insertAdjacentHTML, чтобы вставить его.

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

Есть ли более чистое решение? Моим идеальным решением было бы:

  • Сохраните html-бит в html-файле.
  • Сохраните скрипт в файле .js.
  • Разрешить страницам, использующим скрипт, просто загружать скрипт.

Я пробовал следующие способы, но ни один из них не работает и не отвечает всем этим целям:

1: Преобразуйте html-фрагмент в статический javascript-файл, сохранив при этом жестко запрограммированный html-код внутри. Загрузите его как любой статический скрипт.

К сожалению, это не удается, поскольку теги django не заменяются. Кроме того, в файле javascript по-прежнему присутствует жестко запрограммированный html.

2: Сохраните html-код в виде файла и прочитайте его с помощью вызова fs. Очевидно, что вызовы fs недоступны в нашей среде, и я не уверен, что стоит добавлять необходимую дополнительную библиотеку.

3: Используйте модель предметной области, чтобы получить доступ к html-фрагменту следующим образом:

  • Переместите html-фрагмент в новый html-фрагмент, поместив его в новый скрытый div с уникальным идентификатором.
  • Пусть страница, на которой загружается скрипт, сначала содержит html-фрагмент, в конце раздела {% block content %}, а также содержит html-фрагмент скрипта (если бы я мог заставить это работать, я бы попробовал перенести его в статический js-файл, но по одному изменению за раз).
  • Пусть скрипт использует модель домена, чтобы получить html-бит, содержащий div, получить html-код в виде строки, используя innerHTML, затем удалите скрытый div (чтобы скрытый html-бит не испортил работу приложения).

В модульных тестах это приводит к сбою, который показывает, что новый html-бит не удаляется. Но я скажу, что когда я запускаю приложение локально, оно, похоже, работает, и теги django обрабатываются правильно. Кроме того, если я удалю "скрытый", я не увижу html-код при взаимодействии с сервером. Так что я не совсем уверен, что происходит. Но я думаю, что неработающие тесты показывают, что это решение не совсем корректно.

В любом случае, у этого решения есть свои проблемы:

  • Добавлять нежелательный html-код на страницу рискованно (как показывают неработающие тесты).
  • Для этого требуется, чтобы любая страница, загружающая скрипт, также импортировала соответствующий фрагмент html.

Я мог бы изменить скрытый html-код так, чтобы он не мешал (т.е. выбрать новые имена, а затем отредактировать их в скрипте), но это кажется уродливым и чреватым ошибками.

Есть идеи для более эффективного решения? Я перепробовал множество способов поиска в Интернете, но подозреваю, что неправильно задаю вопрос.

Чтобы устранить проблему с дизайном в вашем приложении Django, в которое вы хотите внедрить HTML, содержащий теги шаблонов Django, с помощью сценария JavaScript, вы можете использовать более простой подход. Цель состоит в том, чтобы разделить HTML и JavaScript в соответствующих файлах, обеспечивая при этом правильную обработку тегов шаблона Django. Вот пошаговое решение:

Шаг 1: Сохраните HTML-код в шаблоне Django Создайте шаблон Django: Сохраните фрагмент HTML-кода в отдельном файле шаблона Django. Это позволяет Django обрабатывать теги шаблона.

<!-- templates/snippets/my_snippet.html -->
<div id="my-snippet">
    <!-- Your HTML with Django template tags -->
    <p>{{ some_variable }}</p>
</div>

Шаг 2: Создайте файл JavaScript Создайте файл JavaScript: Сохраните логику JavaScript в отдельном js-файле. Этот скрипт будет отвечать за ввод HTML-кода в нужное место.

// static/js/inject_snippet.js
document.addEventListener('DOMContentLoaded', function() {
    // Fetch the HTML snippet from the server
    fetch('/get-snippet/')
        .then(response => response.text())
        .then(html => {
            // Find the target element where you want to inject the HTML
            const targetElement = document.getElementById('target-element-id');
            if (targetElement) {
                // Insert the HTML snippet
                targetElement.insertAdjacentHTML('beforeend', html);
            }
        })
        .catch(error => console.error('Error fetching the snippet:', error));
});

Шаг 3: Создайте представление Django для отображения фрагмента HTML Создайте представление Django: создайте представление в Django, которое отображает фрагмент HTML. Это представление обработает теги шаблона и вернет отображенный HTML-код.

# views.py
from django.shortcuts import render

def get_snippet(request):
    # Render the HTML snippet with any context variables
    context = {
        'some_variable': 'Some Value'
    }
    return render(request, 'snippets/my_snippet.html', context)
Map the View to a URL: Add a URL pattern to map the view to a specific URL.


# urls.py
from django.urls import path
from .views import get_snippet

urlpatterns = [
    path('get-snippet/', get_snippet, name='get_snippet'),
]

Шаг 4: Включите JavaScript в свой шаблон Включите JavaScript в свой шаблон: Включите файл JavaScript в свой основной шаблон или в конкретный шаблон, в котором вам нужен фрагмент кода.

<!-- templates/base.html or specific template -->
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Other head elements -->
    <script src="{% static 'js/inject_snippet.js' %}" defer></script>
</head>
<body>
    <!-- Your content -->
    <div id="target-element-id">
        <!-- The HTML snippet will be injected here -->
    </div>
</body>
</html>

Пояснение Разделение задач: Разделяя HTML и JavaScript на соответствующие файлы, вы сохраняете четкую структуру и упрощаете чтение и поддержку кода. Обработка шаблона Django: Фрагмент HTML обрабатывается Django, гарантируя корректное отображение всех тегов шаблона. Динамическое внедрение: JavaScript извлекает обработанный фрагмент HTML с сервера и вводит его в нужное место в DOM. Возможность повторного использования: файл JavaScript может быть включен в любой шаблон, что позволяет повторно использовать решение на разных страницах. Такой подход гарантирует четкое разделение HTML и JavaScript и правильную обработку тегов шаблона Django. Это также позволяет избежать проблем, с которыми вы сталкивались при тестировании жестко закодированных HTML-строк и нежелательных HTML-элементов.

Я последовал замечательному совету Абдулазиза Барката и изменил содержимое <div id=...> на <template id=...>, и все заработало. Я получаю html-строку, получая innerHTML элемента template, и нет необходимости пытаться удалить какие-либо элементы со страницы.

Я также изменил html-фрагмент, чтобы загрузить соответствующий статический файл javascript, поэтому html, использующий скрипты, может просто импортировать этот фрагмент.

Примечание: не устанавливайте shadowrootmode свойство <template> для этого варианта использования. Это все испортило для меня (независимо от того, установил ли я значение "открыто" или "закрыто"), и в этом нет необходимости.

Вернуться на верх