web-dev-qa-db-fra.com

Comment POST a Django forme avec AJAX & jQuery

J'ai consulté des tonnes de tutoriels pour Django AJAX forme, mais chacun d'eux vous indique une façon de le faire, aucune d'entre elles n'est simple et Je suis un peu confus car je n'ai jamais travaillé avec AJAX.

J'ai un modèle appelé "note", un modèle pour celui-ci, et à l'intérieur du modèle, j'ai besoin que chaque fois qu'un élément note envoie le signal stop () (de jQuery Sortables) Django met à jour l'objet.

Mon code actuel:

views.py

def save_note(request, space_name):

    """
    Saves the note content and position within the table.
    """
    place = get_object_or_404(Space, url=space_name)
    note_form = NoteForm(request.POST or None)

    if request.method == "POST" and request.is_ajax:
        msg = "The operation has been received correctly."          
        print request.POST

    else:
        msg = "GET petitions are not allowed for this view."

    return HttpResponse(msg)

JavaScript:

function saveNote(noteObj) {
    /*
        saveNote(noteObj) - Saves the notes making an AJAX call to Django. This
        function is meant to be used with a Sortable 'stop' event.
        Arguments: noteObj, note object.
    */
    var noteID = noteObj.attr('id');

    $.post("../save_note/", {
        noteid: noteID,
        phase: "Example phase",
        parent: $('#' + noteID).parent('td').attr('id'),
        title: $('#' + noteID + ' textarea').val(),
        message: "Blablbla",
    });
}

Le code actuel récupère les données du modèle et les imprime dans le terminal. Je ne sais pas comment je peux manipuler ces données. J'ai vu certaines personnes gérer les données via jqueryforms pour les envoyer à Django.

Comment puis-je accéder aux données envoyées par AJAX et mettre à jour l'objet note?

69
Oscar Carballal

Puisque vous utilisez jQuery, pourquoi ne pas utiliser les éléments suivants:

<script language="JavaScript">
    $(document).ready(function() {
        $('#YOUR_FORM').submit(function() { // catch the form's submit event
            $.ajax({ // create an AJAX call...
                data: $(this).serialize(), // get the form data
                type: $(this).attr('method'), // GET or POST
                url: $(this).attr('action'), // the file to call
                success: function(response) { // on success..
                    $('#DIV_CONTAINING_FORM').html(response); // update the DIV 
                }
            });
            return false;
        });
    });
</script>

EDIT

Comme indiqué dans les commentaires, ce qui précède ne fonctionne parfois pas. Alors essayez ce qui suit:

<script type="text/javascript">
    var frm = $('#FORM-ID');
    frm.submit(function () {
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                $("#SOME-DIV").html(data);
            },
            error: function(data) {
                $("#MESSAGE-DIV").html("Something went wrong!");
            }
        });
        return false;
    });
</script>
113
Sevenearths

Vous pouvez accéder aux données de la demande POST en utilisant le nom de la variable, dans votre cas:

request.POST["noteid"]
request.POST["phase"]
request.POST["parent"]
... etc

L'objet request.POST est immuable. Vous devez affecter la valeur à une variable, puis la manipuler.

Je vous conseillerais d'utiliser ce plugin JQuery , afin que vous puissiez écrire des formulaires HTML normaux et les obtenir ensuite "mis à jour" vers AJAX. Avoir $ .post partout dans votre code est un peu fastidieux.

Utilisez également la vue Réseau sur Firebug (pour Firefox) ou les outils de développement pour Google Chrome afin de pouvoir visualiser ce que vous avez envoyé AJAX appelle.

9
Gerardo Curiel

Une chose à surveiller est de renvoyer le formulaire sous forme de fichier HTML coupé à un modal.

Views.py

@require_http_methods(["POST"])
def login(request):
form = BasicLogInForm(request.POST)
    if form.is_valid():
        print "ITS VALID GO SOMEWHERE"
        pass

    return render(request, 'assess-beta/login-beta.html', {'loginform':form})

Vue simple pour retourner le code HTML coupé

formulaire html snippé

<form class="login-form" action="/login_ajx" method="Post"> 
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h4 class="modal-title" id="header">Authenticate</h4>
  </div>
  <div class="modal-body">
        {%if form.non_field_errors %}<div class="alert alert-danger">{{ form.non_field_errors }}</div>{%endif%}
        <div class="fieldWrapper form-group  has-feedback">
            <label class="control-label" for="id_email">Email</label>
            <input class="form-control" id="{{ form.email.id_for_label }}" type="text" name="{{ form.email.html_name }}" value="{%if form.email.value %}{{ form.email.value }}{%endif%}">
            {%if form.email.errors %}<div class="alert alert-danger">{{ form.email.errors }}</div>{%endif%}
        </div>
        <div class="fieldWrapper form-group  has-feedback">
            <label class="control-label" for="id_password">Password</label>
            <input class="form-control" id="{{ form.password.id_for_label }}" type="password" name="{{ form.password.html_name}}" value="{%if form.password.value %}{{ form.password.value }}{%endif%}">
            {%if form.password.errors %}<div class="alert alert-danger">{{ form.password.errors }}</div>{%endif%}
        </div>
  </div>
  <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<input type="submit" value="Sign in" class="btn btn-primary pull-right"/>
</div>
</form>

page contenant le modal

<div class="modal fade" id="LoginModal" tabindex="-1" role="dialog">{% include "assess-beta/login-beta.html" %}</div>

Utilisez la balise include pour charger la capture lors du chargement de la page afin qu’elle soit disponible lorsque vous ouvrez le modal.

Modal.js

$(document).on('submit', '.login-form', function(){
$.ajax({ 
    type: $(this).attr('method'), 
    url: this.action, 
    data: $(this).serialize(),
    context: this,
    success: function(data, status) {
        $('#LoginModal').html(data);
    }
    });
    return false;
});

L'utilisation de .on () dans ce cas fonctionne comme .live (), la clé liant l'événement de soumission non pas au bouton mais au document.

4
JUhrig

Comme les autres réponses fonctionnent, je préfère utiliser le jQuery Form Plugin . Il soutient pleinement ce que vous voulez et plus encore. La vue de publication est traitée comme d'habitude dans la partie Django, renvoyant simplement le code HTML en cours de remplacement.

Sur le serveur, votre code Django peut traiter la AJAX de la même manière qu’il traite les autres soumissions de formulaires. Par exemple,

views.py

def save_note(request, space_name):

    """
    Saves the note content and position within the table.
    """
    place = get_object_or_404(Space, url=space_name)
    note_form = NoteForm(request.POST or None)

    if request.method == "POST" and request.is_ajax():        
        print request.POST
        if note_form.is_valid():
            note_form.save()
            msg="AJAX submission saved"
        else:
            msg="AJAX post invalid"
    else:
        msg = "GET petitions are not allowed for this view."

    return HttpResponse(msg)

J'ai supposé que votre NoteForm est un ModelForm - comme il se doit - il a donc une méthode de sauvegarde. Notez qu’en plus d’ajouter la commande save(), j’ai changé votre request.is_ajax En request.is_ajax(), ce que vous voulez (si vous utilisez request.is_ajax Votre Le code vérifiera simplement si la requête a une méthode appelée is_ajax, ce qui est évidemment le cas).

2
user931920

La plupart des exemples d'utilisation de AJAX POST avec Django), y compris l'exemple officiel:

https://docs.djangoproject.com/fr/1.9/topics/class-based-views/generic-editing/#ajax-example

sont corrects quand ModelForm.clean() ne produit aucune erreur (form_valid). Cependant, ils ne réalisent pas de tâche difficile: traduction de ModelForm erreurs via AJAX réponse au côté client Javascript/DOM.

Mon application enfichable utilise AJAX) le routage des réponses avec les modèles de vue côté client pour afficher automatiquement la vue basée sur les classes AJAX post ModelForm erreurs de validation similaires à la ils seraient affichés dans HTTP POST traditionnel:

https://Django-jinja-knockout.readthedocs.org/en/latest/forms.html#ajax-forms-processinghttps: //Django-jinja-knockout.readthedocs. org/fr/latest/viewmodels.html

Jinja2 et Django) sont pris en charge par le moteur de modèle.

1
Dmitriy Sintsov