2009-09-29 5 views
5

На днях я написал несколько AJAX для приложения Django, над которым я работал.лучший способ сделать ajax в django

Я родом из Ruby on Rails, поэтому я не сделал много на пути сырой JS.

Так на основе Rails' частичный, я что-то похожее на следующее в своем роде псевдокод, не потею детали:

1) функция JS с помощью Ajax.Updater прототипа („tablediv“ является идентификатором таблиц я хотел обновить Ajaxily и URL-адрес, указывающий на правильное точку зрения Джанго)

function updateTable(){ 
     new Ajax.Updater('tablediv',url {params: params....etc 

2) вида Джанго, который получил новые данные для заполнения таблицы:

def ajaxTable 
    objects = Objects.object.all... 
    return render_to_response('ajaxtable.html',objects) 

3) ajaxtable.html был просто своего рода Rails «частичный» поэтому в основном стол без <table></table> ...:

<th>{{object.data}}</th> 
    <td>{{object.moredata}}</td> 

так мой актуальный вопрос:

Это казалось мне Hacky , Я как бы выбросил его вместе, устав искать в Интернете то, что хотел.

Это так, как это делается? Он отлично работает, я просто не знаю, что знаю, знаете ли?

ответ

1

Что именно кажется взломанным? Похоже, это совершенно правильный способ сделать что-то.

Я предполагаю, что альтернатива будет serialising json и отправка его обратно в javascript templating фрагмент.

+0

Это то, с чем я играл, но в то время я не знал, как много javascript, как я знаю, поэтому просто отправьте объекты как JSON, сделайте из него объектные литералы javascript, а затем tablediv.innerHTML = foo ? – Joel

+0

JSON * - это объектный литерал, поэтому приятная вещь об использовании его в javascript заключается в том, что вам не нужно ничего с ним делать, чтобы на самом деле использовать его, как только он у вас есть. Мне нравится использовать JSON в сочетании с системой шаблонов, с которой я связан выше (jquery, а не прототип, извините), поскольку вы можете просто передать JSON, вернувшись прямо к шаблону, который вы настроили, и он будет работать. – Steerpike

2

Независимо от того, что, вы будете нуждаться по крайней мере, две вещи:

  1. Ваш Javascript код, чтобы сделать вызов (у вас есть это)

  2. сервера кода на стороне для обработки запрос (это ваше мнение и url-config)

Абсолютно ничего не «хаки» об этом.

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

Итак, я думаю, что у вас есть правильная идея. Продолжать.

+0

приятно, спасибо за ответ, я закончил проект и переехал, но с тех пор он меня прослушивал (когда я нахожусь в середине чего-то, что я не могу перестать спрашивать на форуме или переполнении стека. «т иметь терпение :), хорошо знать, что мои инстинкты не совсем ridiculus – Joel

5

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

Однако есть некоторые полезные вещи, которые вы можете сделать с этой помощью.

1) Уровень шаблона

Убедитесь, что вы "django.core.context_processors.request" в настройках TEMPLATE_CONTEXT_PROCESSORS.Тогда вы можете это сделать;

{% if not request.is_ajax %} 
<html> 
    <head> 
    ... 
    </head> 
    <body> 
    ... 
{% endif %} 
actual content 
{% if not request.is_ajax %} 
</body> 
</html> 
{% endif %} 

В принципе, то говорят, что это страница/тест/Вы можете сделать запрос на браузер и получить полное содержание или запрос через JavaScript и просто получить содержание. Есть где-то блог-справочник, который объясняет это более подробно, но я не могу найти его в данный момент.

2) По мнению

В шаблоне мы просто получить доступ к объекту запроса в шаблоне. В представлении вы можете делать очень похожие вещи.

def my_view(request): 
    if requst.is_ajax(): 
     # handle for Ajax requests 

    # otherwise handle 'normal' requests 
    return HttpResponse('Hello world') 

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

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

+0

Это кажется очень умным, приходя от использования встроенного рубина, который обращается ко мне ... может быть слишком умным ... – Joel

+0

хах нет html в комментариях ... – Joel

+0

слишком умный? Мне это очень нравится. Вы можете полностью Ajaxify больших бит сайта быстро, к сожалению, нет способа иметь более одного «блока ajax» для каждого шаблона ... Хм, интересно, как вы могли это сделать. –

4

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

У меня есть модель, представляющая контактные лица.

(общий) вид, чтобы получить один ContactPerson выглядит следующим образом:

def contcactperson_detail_view(request, name): 
    try: 
     person = ContactPerson.objects.get(slug=name) 
    except: 
     raise Http404 
    if request.is_ajax(): 
     return contcactperson_detail_view_ajax(request, person) 
    return list_detail.object_detail(
      request, 
      queryset = ContactPerson.objects.all(), 
      object_id = person.id, 
      template_object_name = "contactperson", 
     ) 

@render_to('cms/contactperson_detail_ajax.html')  
def contcactperson_detail_view_ajax(request, person): 
    return {'contactperson':person, 'is_ajax':True} 

Шаблон для визуализации представления, который обрабатывает один ContactPerson называется contcactperson_detail_view.html:

{% extends "index.html" %} 
{% block textpane %} 

<h1 id="mainheader">{{ contactperson.first_name }} {{ contactperson.family_name }} </h1> 
<div class="indentation">&nbsp;</div> 
{% include 'cms/contactperson_detail_photo.html' %}                           
<div id="text_pane"> 

{% include 'cms/contactperson_detail_textpane.html' %} 
</div> 
{% endblock %} 

Она включает в себя два суб- шаблоны

contactperson_detail_textpane.html 


<p>{{ contactperson.description }}</p> 
<ul> 
    <li> 
     <dl> 
      <dt>Email</dt> 
      <dd> 
       {{ contactperson.mail }} 
      </dd> 
     </dl> 
    </li> 
    <li> 
     <dl> 
      <dt>Contact Person for</dt> 
      <dd> 
       <ul> 
       {% for c in contactperson.categories.all %} 
        <li><a href="{% url category-view c.slug %}">{{ c }}</a></li> 
       {% endfor %} 
       </ul> 
      </dd> 
     </dl> 
    </li> 
</ul> 

и contactperson_detail_photo.html

{% with contactperson.photo.detailphoto as pic %} 
    {% with pic.url as pic_url %}  
    <div {% if not is_ajax %}id='imageContainer'{% endif %} style="float: right;padding-right:0.5em; 
            padding-bottom: 1em; padding-left:0.5em;clear:both; 
            width:{{ pic.width }}px"> 
     <div style="width:{{ pic.width}}px">      
       <img style="clear:both" src="{{ pic_url }}" alt="{{ i.name }}"/> 
     </div>                              
    </div> 
    {% endwith %} 
{% endwith %} 

этот 3 шаблона будут использоваться, если запрос не является ajax.

Но если запрос является ajax, contcactperson_detail_view вернет представление contcactperson_detail_view_ajax, которое использует шаблон contactperson_detail_ajax.html для рендеринга. И этот шаблон выглядит следующим образом:

<h1>{{ contactperson.first_name }} {{ contactperson.family_name }}</h1> 
{% include 'cms/contactperson_detail_photo.html' %}                           
{% include 'cms/contactperson_detail_textpane.html' %} 

Так он использует те же суб-шаблоны, но ничего не расширяясь, поэтому только необходимо Разметка доставки. Поскольку представление ajax передает is_ajax = True в шаблон, его можно использовать для настройки незначительных вещей, например, для установки правильных идентификационных атрибутов.

Контекстно-процессорный или дополнительный url-conf не требуется.

Наконец код Javascript:

$("#contact_person_portlet a").click(function(event){ 
     event.preventDefault(); 
     $.ajax({ 
      type: "GET", 
      url: event.target.getAttribute('href'), 
      success: function(msg){ 
       overlay(msg); 
      } 
     }); 
    }); 

Надеется, что это будет полезно для некоторых людей. Если да, оставьте комментарий!

+0

Я считаю, что вы можете реализовать более простое решение, используя один вид и один и тот же шаблон для ajax/non-ajax, но наследуя от другого базового шаблона в зависимости от контекстной переменной. См. Http://stackoverflow.com/questions/4014156/django-templates-sysntax-error/4018629#4018629 за ответ, который я дал другому вопросу в этой строке –

+0

действительно очень элегантный – vikingosegundo

Смежные вопросы