2012-11-06 5 views
12

Używam wtyczki AjaxForm do przesyłania mojego formularza bez odświeżania. na przykład:Django - Jak wyświetlać wiadomości pod funkcją ajax

$('#my_form_id').ajaxForm(function(){ 

     //something on success or fail 
    }); 

to działa poprawnie. po kliknięciu przycisku Wyślij zapisuje dane formularzy bez odświeżania. Ale przed tym; Miałem django wiadomości na mój plik szablonu jak:

{% for message in messages %} 
    <div id="notice" align="center"> 
     {{ message }} 
    </div> 
{% endfor %} 

co ten kod robi wyświetla powiadomienia, jeśli po zapisany poprawnie lub coś nie powiodło się.

teraz; nie mogę tego zrobić. Nie rozumiem, w jaki sposób mogę używać tych tagów wiadomości z funkcjami ajax.

to tylko zapisuje post. brak powiadomień.

dziękuję.

edit:

add_post url: url(r'^admin/post/add/$', view='add_post',name='add_post'),

powiązany widok:

@login_required(login_url='/login/') 
def add_post(request): 
    template_name = 'add.html' 
    owner = request.user 
    if request.method == "POST": 
     form = addForm(request.POST) 
     if form.is_valid(): 
      titleform = form.cleaned_data['title'] 
      bodyform = form.cleaned_data['body'] 
      checkform = form.cleaned_data['isdraft'] 

      n = Post(title=titleform, body=bodyform, isdraft=checkform, owner=owner) 
      n.save() 
      messages.add_message(request, messages.SUCCESS, 
       'New post created successfully!') 
     else: 
      messages.add_message(request, messages.WARNING, 
       'Please fill in all fields!') 
    else: 
     form = addForm() 
    return render_to_response(template_name, {'form': form, 'owner': owner,}, 
     context_instance=RequestContext(request)) 
+0

Powinieneś wkleić swój adres URL i widok. – jpic

+0

dodano adres URL i część widoku. – alix

Odpowiedz

10

To są narzędzia/metody, które pomogły mi rozwiązać problem. Po pierwsze, mam metoda narzędzie pomocnik nazywany render_to_json:

# `data` is a python dictionary 
def render_to_json(request, data): 
    return HttpResponse(
     json.dumps(data, ensure_ascii=False), 
     mimetype=request.is_ajax() and "application/json" or "text/html" 
    ) 

Mam messages.html szablon do renderowania niezbędną HTML dla wiadomości podręcznego (ów):

{% for message in messages %} 
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> 
{% endfor %} 

Kiedy utworzyć wiadomość w odpowiedzi Żądanie AJAX, używam Django render_to_string do pakowania wiadomości do ciągu, który zostanie zapisany w słowniku data, który następnie używa mojego render_to_json, aby zwrócić odpowiednią odpowiedź:

def my_custom_view(request) 
    # ... your view code 
    data = { 
     'msg': render_to_string('messages.html', {}, RequestContext(request)), 
    } 
    return render_to_json(request, data) 

Następnie w moim jQuery $.post(...) funkcji zwrotnej, to należy sprawdzić, czy obiekt response posiada atrybut msg, a następnie wstawić zawartość response.msg do DOM, gdzie chcę to musi być, z przejściami jQuery razie potrzeby.Moja base.html szablon zawiera pojemnik <ul> dla komunikatów:

<ul id="popup-messages-content"> 
    {% include 'messages.html' %} 
</ul> 

Zauważ, że powyższy zawierający podstawowe messages.html dla przypadku, gdy chcesz wyświetlić wiadomości na rzeczywistej stronie obciążenia (nie AJAX żądanie) - to jest puste, jeśli nie ma żadnych wiadomości, ale <ul> jest nadal dostępna do przesyłania wiadomości odbieranych w AJAX.

ostatni kawałek jest funkcja JavaScript (wymaga jQuery) używać w żadnej $.post(...) callbacków pokazać komunikaty:

function showPopupMessage(content) { 
    var elMessages = $('#popup-messages-content'); 
    if (elMessages.length && content) { 
     elMessages.html(content); 
    } 
} 
+0

Jeśli dostarczyłeś potrzebną odpowiedź, możesz oznaczyć ją jako taką? Dzięki! –

+0

To jest krępujące ... Przepraszam za spóźnioną odpowiedź. po prostu to przyjąłem :) – alix

3

Oto prosty pomysł.

Dodaj zastępczy dla wiadomości w layout.html ta umożliwia dołączanie nowych wiadomości w javascript:

<div id="messages"> 
{% for message in messages %} 
    <div id="notice" align="center"> 
     {{ message }} 
    </div> 
{% endfor %} 
</div> 

Zamiast:

{% for message in messages %} 
    <div id="notice" align="center"> 
     {{ message }} 
    </div> 
{% endfor %} 

W add.html, dodać kolejny na przykład:

{% if messages %} 
<ul class="hidden-messages" style="display:none"> 
    {% for message in messages %} 
     <div id="notice" align="center"> 
      {{ message }} 
     </div> 
    {% endfor %} 
</ul> 
{% endif %} 

A ajaxForm będzie wyglądać na przykład:

$('#your_form_id').ajaxForm({ 
    success: function(responseText) { 
     var newMessages = $(responseText).find('.hidden-messages').html(); 
     $('#messages').append(newMessages); 
    }, 
}); 
+0

hmmm. czy możesz napisać mi jakiś wyjaśniający kod? rozumiem to poprawnie? – alix

+0

Próbuję teraz. dziękuję – alix

5

znalazłem łatwiejszy sposób to zrobić here, wziąłem niektóre z tych pomysłów i to był mój wynik:

po prostu tworzyć swoje wiadomości jak zawsze i przed wysłaniem odpowiedzi je umieścić na liście dicts:

django_messages = [] 

for message in messages.get_messages(request): 
    django_messages.append({ 
     "level": message.level, 
     "message": message.message, 
     "extra_tags": message.tags, 
}) 

Następnie należy dodawać żadnych danych i wiadomości i szeregować je, np:

data = {} 
data['success'] = success 
data['messages'] = django_messages 

return HttpResponse(simplejson.dumps(data), content_type="application/json") 

Wreszcie w swojej AJAX:

success: function(data){ 
           success = data.success; 
           update_messages(data.messages); 
           if (success){ 
            ...                    
           } 
          }, 

a funkcja update_messages:

function update_messages(messages){ 
$("#div_messages").html(""); 
$.each(messages, function (i, m) { 
       $("#div_messages").append("<div class='alert alert-"+m.level+"''>"+m.message+"</div>"); 
      }); 

}

Działa doskonale i bardzo łatwo mi było wdrożyć

+1

Czy zmienne 'm.div_messages' nie powinny być odpowiednio" m.level "i" m.message "? – sHtev

+0

Również nie chcesz 'message.level_tag' zamiast' message.level'? – sHtev

+0

Masz rację co do zmiennych, to był tylko błąd podczas tłumaczenia kodu na angielski. O level_tag vs level Nie jestem pewien, nie używam go na moim kodzie. Dzięki za poprawki. – steven2308