Добавить тег шаблона Django с помощью Jquery

#javascript #jquery #django #django-templates

#javascript #jquery #django #django-шаблоны

Вопрос:

Я хочу создать меню, в котором я могу установить одну ссылку, выделенную с помощью тега {% block %}. У меня есть что-то подобное в моем Javascript:

 <loop>
$('#a-div').append('{% block '   variable   ' %} <a href...</a> {% endblock %}')
<endloop>
  

В исходном коде это отображается как «{% block Home %}»

Как я могу заставить jQuery добавлять это не как строку, а как тег шаблона?

Ответ №1:

Вы не можете. По крайней мере, без выполнения AJAX-запроса к шаблону Django. В вашем случае это было бы медленно и приводило бы к ненужным дополнительным запросам. Оно того просто не стоит. Вы можете вставлять фрагменты из шаблонов Django с помощью jQuery, используя, например, функцию jQuery load . Но вы не можете заменить конкретный {% block %} тег, потому что ко времени запуска jQuery шаблон уже обработан (и ссылки на теги блоков удалены). Но это не та ситуация, когда вы должны делать это в любом случае.

Почему бы вам не выделить меню с помощью класса CSS? Вот мое обычное решение этой проблемы:

  1. Создайте файл с именем base_extras.py в одной из ваших templatetags папок. Если у вас его нет, создайте его в соответствующей папке.
  2. Внутри base_extras.py вставьте этот код:

     from django import template
    from django.core.urlresolvers import reverse
    
    register = template.Library()
    
    @register.simple_tag
    def navactive(request, urls):
        if request.path in ( reverse(url) for url in urls.split() ):
            return "active"
        return ""
      
  3. Теперь в вашем шаблоне, в ваших меню в вашем базовом шаблоне, сделайте что-то вроде этого:

     <ul class="menu">
        <li class="home {% navactive request 'home' %}"><a href="{% url home %}">Home</a></li>
        <li class="contact {% navactive request 'contact' %}"><a href="{% url contact %}">Contact</a></li>
        <li class="signup {% navactive request 'signup' %}"><a href="{% url signup %}">Sign up</a></li>
    </ul>
      
  4. Это приведет к тому, что меню, в котором в данный момент находится ваш URL, будет иметь active класс. Затем в вашем CSS просто добавьте специальный класс для элемента меню с active , чтобы он выглядел немного иначе, чем другие меню.

     ul.menu li.active {background: red; color: white;}
      

И если вам понадобится изменить активное меню с помощью jQuery, вы можете просто удалить active класс во всех меню и добавить его во вновь выбранные меню:

 $('ul.menu li').removeClass('active').find('.home').addClass('active'); // for example
  

Комментарии:

1. Спасибо, мне действительно понравилось это решение. Но на самом деле это не решает мою проблему. Вероятно, мне следует объяснить немного лучше. Я получаю имя и цель ссылки меню из запроса ajax. итак, в моем цикле for я хочу использовать название ссылки меню в качестве названия блока. Я делаю это просто для развлечения, поэтому я осознаю, что это может быть очень глупым поступком.

2. @Pecock: К сожалению, это невозможно, AFAIK. Единственным способом было бы отправить запрос jQuery к другому шаблону Django и вставить возвращаемое содержимое в правильное положение с помощью id или class , или как угодно. Но вы не сможете добавлять новые блоки или обновлять старые блоки в своем коде django с помощью jQuery.

3. Что ж, спасибо, ребята. Я вроде бы нашел решение, но оно плохое. Я только что передал переменную «active_menu» из шаблона и сохранил ее в скрытом поле. Затем сравнил его в меню. В следующий раз я обязательно сделаю это лучше

Ответ №2:

Вы не можете сделать это таким образом. Теги шаблона Django обрабатываются на стороне сервера еще до отправки страницы в браузер. Javascript (включая jQuery), с другой стороны, вызывается в браузере после получения страницы с сервера.

Что вы можете сделать, так это предварительно перенести содержимое {% block %} тега в переменную JS и использовать его в коде jQuery:

 var blockContent = "{% block Home %} ... {% endblock %}";
// ...
$("#a-div").append(blockContent);
  

Если вам нужно выбрать более одного блока (как вы, кажется, указали в предоставленном вами примере кода), вы могли бы прибегнуть к массиву предварительно обработанных блоков.

Ответ №3:

Лучше всего создать прокси-представление, которое выполняет текущий ваш AJAX-запрос, обрабатывает результаты, как это сделал бы javascript, а затем возвращает все, что вы пытаетесь получить из системы шаблонов Django.

Затем, вместо текущего вызова AJAX, вы вызываете свой собственный view вместо этого. Django выполняет обработку в представлении, как и должно быть, вы получаете точный контроль над тем, что возвращается в ваш javascript, и это все еще только один (на стороне клиента) вызов сервера.