Обновите div в Django, используя JQuery и AJAX

4

Я пытаюсь обновить определенную часть моей страницы с помощью AJAX и JQuery (в Django). Как я могу заставить его повторно отображать только div, а не всю страницу.

    // In my template
    var tag_cloud_floor = function(floor) {
    $.ajax({ url: "/{{ user }}/{{ tag }}/",
                     data: {tag_cloud_floor: floor},
                     type: 'POST',
                     success: function(data) {
                         $('#tag_cloud).html(data);
                     },
    });

};

Вот мой взгляд.

@login_required
def tag_page(request, username, tag):
  if username == request.user.username:
    tags = request.user.userprofile.tag_set.all()

    if request.is_ajax() and request.POST:
      floored_tags = []
      for t in tags:
        if t.item_set.all().count() >= int(request.POST['tag_cloud_floor']):
          floored_tags.append(t)
      tags = floored_tags

    tag = Tag.objects.get(title=tag)
    items = tag.item_set.all()
    return render_to_response("tag_page.html", { 'user': request.user , 
                                              'tag': tag,
                                             'tags': tags,
                                            'items': items })
  else:
  return HttpResponseRedirect('/' + request.user.username + '/')

В настоящее время он помещает всю html-страницу в div #tag_page. Я хочу, чтобы он заменил старый #tag_page div новым #tag_page div. Если я заменил $('#tag_cloud').html(data); на $('body').html(data);, он обновит всю страницу до того, как она должна быть, но я считаю, что обновление всей страницы является отходом.

Если есть лучший способ сделать это, дайте мне знать.

  • 0
    также возможно ли отделить работу ajax от представления, отличного от представления загрузки начальной страницы?
  • 1
    Конечно, вы можете отделить функциональность; создайте отдельное представление с отдельным URL-адресом, и оно будет возвращать только данные тегов. Теперь, если вы вернете его в JSON и восстановите теги на странице или вернете его в виде фрагмента HTML и просто вставите его в страницу, решать только вам. Если вы планируете много AJAX на вашем сайте, проверьте django-pneon
Теги:

3 ответа

7
Лучший ответ

Во-первых, похоже, что ваш код поврежден - это не действительная инструкция Javascript/jQuery:

$('#tag_cloud).html(data);

Вам нужно добавить отсутствующую цитату:

$('#tag_cloud').html(data);

Что касается обновления только одного div, я бы извлек содержимое этого div в отдельный шаблон my_div.html, включив его в шаблон главной страницы, используя {% include "my_div.html" %}. Затем, в моем представлении AJAX, я бы отобразил и вернул только то, что вынесло my_div.html.

  • 0
    $ ( '# Tag_cloud') HTML (данные). на самом деле является действительной функцией (я просто забыл вторую цитату). я закончил тем, что сохранил это, включая второй файл, и передал данные этому файлу.
  • 0
    @Josh: Джош: Да, и я имел в виду пропущенную цитату.
Показать ещё 1 комментарий
11

Используйте load:

$('#tag_cloud').load(' #tag_cloud')

(Обратите внимание на начальное пространство в параметре load, это указывает пустую строку [которая оценивает текущую страницу] в качестве источника и "#tag_cloud" в качестве загружаемого фрагмента)

Это фактически загрузит #tag_cloud (включая его внешний html) в #tag_cloud, так что вы существенно получите следующую структуру в DOM:

<div id="tag_cloud">
    <div id="tag_cloud">
        <span>tag</span> ...

Чтобы исправить это, просто unwrap дети:

$('#tag_cloud').load(' #tag_cloud', function(){$(this).children().unwrap()})

О, кстати... вы можете попробовать это здесь, на SO! Просто вставьте следующее в свою консоль Firebug и посмотрите, как перезагрузка боковой панели. Вы заметите, что код сценария просунул; что jQ HTML-фильтры безопасности отключают элементы <script> для вас (что может раздражать порой).

$('#sidebar').load(' #sidebar', function(){$(this).children().unwrap()})
  • 1
    Сначала я отклонил этот ответ, затем проверил документы load () , обратил внимание на раздел «Загрузка фрагментов страницы» и отменил голосование :-) Хороший материал, хотя он излишне регенерирует всю страницу.
  • 0
    @Tomasz Томас, спасибо, что читаете документы! И да, я бы обычно использовал поршень (или просто простое представление, которое возвращает данные в формате json) для таких взаимодействий, но OP, казалось, пытался сделать то, для чего предназначалась load .
3

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

Скажем, страница /usual_page/ имеет этот шаблон:

{% extends "another_template.html" %}
{% block title %}Usual page{% endblock %}
{% block content %}...{% endblock %}
{% block my_widget %}widget code{% endblock %}

Если вы установите промежуточное программное обеспечение и сделаете запрос GET, например /usual_page/?partial=my_widget, он отправит клиенту эти данные:

{"blocks": {"my_widget": "widget code"}}

Или, если вы выполните /usual_page/?partial=title,content, он отправит следующее:

{"blocks": {"title": "Usual page", "content": "..."}}

Также можно запросить другие блоки, которые находятся в родительском шаблоне. Неважно, где находится блок в иерархии, имеет значение только то, что оно присутствует на обычной странице (без параметра ?partial).

В репозиторий BitBucket у меня есть демонстрационный проект, в котором есть модуль, который автоматизирует работу. Он позволяет использовать метод History.pushState и загружать части страниц и вставлять их в документ.

  • 0
    Это очень умно. Я собирался написать что-то подобное сам. Но я вижу, что этот ответ с 2011 года, есть ли в Django что-то подобное встроенное или нам все еще нужно это решение?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню