Wie integriere ich Ajax in Django-Anwendungen?

264

Ich bin neu in Django und ziemlich neu in Ajax. Ich arbeite an einem Projekt, in dem ich die beiden integrieren muss. Ich glaube, dass ich die Prinzipien hinter beiden verstehe, aber keine gute Erklärung für beide zusammen gefunden habe.

Könnte mir jemand kurz erklären, wie sich die Codebasis ändern muss, wenn sich die beiden integrieren?

Kann ich beispielsweise weiterhin HttpResponseAjax verwenden oder müssen sich meine Antworten bei Verwendung von Ajax ändern? Wenn ja, können Sie bitte ein Beispiel dafür geben, wie sich die Antworten auf die Anfragen ändern müssen? Wenn es einen Unterschied macht, sind die Daten, die ich zurückgebe, JSON.

tjons
quelle

Antworten:

636

Auch wenn dies nicht ganz im Sinne von SO ist, ich liebe diese Frage, weil ich die gleichen Probleme hatte, als ich anfing, also werde ich Ihnen eine Kurzanleitung geben. Offensichtlich verstehen Sie die Prinzipien dahinter nicht (nehmen Sie es nicht als Beleidigung, aber wenn Sie es tun würden, würden Sie nicht fragen).

Django ist serverseitig . Angenommen, ein Client geht zu einer URL, Sie haben eine Funktion views, die das, was er sieht, rendert und eine Antwort in HTML zurückgibt. Lassen Sie es uns in Beispiele aufteilen:

views.py:

def hello(request):
    return HttpResponse('Hello World!')

def home(request):
    return render_to_response('index.html', {'variable': 'world'})

index.html:

<h1>Hello {{ variable }}, welcome to my awesome site</h1>

urls.py:

url(r'^hello/', 'myapp.views.hello'),
url(r'^home/', 'myapp.views.home'),

Das ist ein Beispiel für die einfachste Verwendung. Going to 127.0.0.1:8000/helloMittel zur Anfrage - hello()Funktion, zu gehen 127.0.0.1:8000/homedie zurückkehrenindex.html die Variablen zurückgegeben und alle Variablen wie gewünscht ersetzt (wahrscheinlich wissen Sie das alles inzwischen).

Lassen Sie uns jetzt über AJAX sprechen . AJAX-Aufrufe sind clientseitiger Code, der asynchrone Anforderungen ausführt. Das klingt kompliziert, bedeutet aber einfach, dass es im Hintergrund eine Anfrage für Sie ausführt und dann die Antwort bearbeitet. Wenn Sie also einen AJAX-Aufruf für eine URL ausführen, erhalten Sie dieselben Daten, die Sie als Benutzer erhalten würden, wenn Sie an diesen Ort gehen.

Zum Beispiel ein AJAX-Aufruf an 127.0.0.1:8000/hello das gleiche Ergebnis zurück, als ob Sie es besucht hätten. Nur dieses Mal haben Sie es in einer JavaScript-Funktion und können damit umgehen, wie Sie möchten. Schauen wir uns einen einfachen Anwendungsfall an:

$.ajax({
    url: '127.0.0.1:8000/hello',
    type: 'get', // This is the default though, you don't actually need to always mention it
    success: function(data) {
        alert(data);
    },
    failure: function(data) { 
        alert('Got an error dude');
    }
}); 

Der allgemeine Prozess ist folgender:

  1. Der Anruf geht an die URL 127.0.0.1:8000/hello als hätten Sie einen neuen Tab geöffnet und selbst gemacht.
  2. Wenn dies erfolgreich ist (Statuscode 200), führen Sie die Funktion für den Erfolg aus, die die empfangenen Daten alarmiert.
  3. Wenn dies fehlschlägt, führen Sie eine andere Funktion aus.

Was würde hier nun passieren? Sie würden eine Warnung mit "Hallo Welt" darin erhalten. Was passiert, wenn Sie einen AJAX-Anruf nach Hause tätigen? Gleiches gilt für Sie<h1>Hello world, welcome to my awesome site</h1> .

Mit anderen Worten - AJAX-Anrufe sind nichts Neues. Sie sind nur eine Möglichkeit für Sie, dem Benutzer das Abrufen von Daten und Informationen zu ermöglichen, ohne die Seite zu verlassen, und sorgen für ein reibungsloses und sehr übersichtliches Design Ihrer Website. Einige Richtlinien, die Sie beachten sollten:

  1. Lernen Sie jQuery . Ich kann das nicht genug betonen. Sie müssen es ein wenig verstehen, um zu wissen, wie Sie mit den empfangenen Daten umgehen sollen. Sie müssen auch einige grundlegende JavaScript-Syntax verstehen (nicht weit von Python, Sie werden sich daran gewöhnen). Ich empfehle Envatos Video-Tutorials für jQuery nachdrücklich. Sie sind großartig und bringen Sie auf den richtigen Weg.
  2. Wann soll JSON verwendet werden? . Sie werden viele Beispiele sehen, in denen sich die von den Django-Ansichten gesendeten Daten in JSON befinden. Ich habe darauf nicht näher eingegangen, weil es nicht wichtig ist, wie es geht (es gibt viele Erklärungen) und viel wichtiger, wann . Und die Antwort darauf lautet: JSON-Daten sind serialisierte Daten. Das heißt, Daten, die Sie bearbeiten können. Wie bereits erwähnt, ruft ein AJAX-Aufruf die Antwort ab, als ob der Benutzer dies selbst getan hätte. Angenommen, Sie möchten sich nicht mit dem gesamten HTML-Code herumschlagen und stattdessen Daten senden (möglicherweise eine Liste von Objekten). JSON ist dafür gut geeignet, da es als Objekt gesendet wird (JSON-Daten sehen aus wie ein Python-Wörterbuch). Anschließend können Sie darüber iterieren oder etwas anderes tun, das das Durchsuchen von nutzlosem HTML überflüssig macht.
  3. Fügen Sie es zuletzt hinzu . Wenn Sie eine Web-App erstellen und AJAX implementieren möchten, tun Sie sich selbst einen Gefallen. Erstellen Sie zunächst die gesamte App ohne AJAX. Sehen Sie, dass alles funktioniert. Beginnen Sie dann und erst dann mit dem Schreiben der AJAX-Aufrufe. Das ist ein guter Prozess, mit dem Sie auch viel lernen können.
  4. Verwenden Sie die Entwicklertools von Chrome . Da AJAX-Aufrufe im Hintergrund ausgeführt werden, ist es manchmal sehr schwierig, sie zu debuggen. Sie sollten die Chrome-Entwicklertools (oder ähnliche Tools wie Firebug) und console.logDinge zum Debuggen verwenden. Ich werde es nicht im Detail erklären, sondern nur googeln und es herausfinden. Es wäre sehr hilfreich für Sie.
  5. CSRF-Bewusstsein . Denken Sie zum Schluss daran, dass für Post-Anfragen in Django das erforderlich ist csrf_token. Bei AJAX-Aufrufen möchten Sie häufig Daten senden, ohne die Seite zu aktualisieren. Sie werden wahrscheinlich Probleme haben, bevor Sie sich endlich daran erinnern - warten Sie, Sie haben vergessen, das zu senden csrf_token. Dies ist eine bekannte Straßensperre für Anfänger in der AJAX-Django-Integration, aber nachdem Sie gelernt haben, wie man es schön spielt, ist es ganz einfach.

Das ist alles, was mir in den Sinn kommt. Es ist ein großes Thema, aber es gibt wahrscheinlich nicht genug Beispiele. Arbeiten Sie sich einfach langsam dorthin vor, Sie werden es irgendwann bekommen.

Yuvi
quelle
1
Vielen Dank. Ich war einfach da, wo du bist, ich kenne das Gefühl. Was das Chatten betrifft - im Allgemeinen ja, aber momentan nicht (auch für bestimmte Fragen haben Sie ... nun ... die gesamte SO).
Yuvi
2
PS: Die Videos, die ich verlinkt habe, haben eine ganze Woche lang AJAX gewidmet. Im Ernst, gehen Sie sie durch. Sie sind fantastisch
yuvi
Danke @yuvi dafür! Ich stelle mir die gleiche Frage zu AJAX. Außerdem bin ich mir nicht sicher, wann ich AJAX verwenden muss oder nicht. Ich verstehe zum Beispiel, dass ich Javascript benötige, um Bootstrap- Modalformulare zu verarbeiten, aber ich verstehe nicht, ob es mit AJAX zusammenhängt oder nicht. Und im Ernst, ich muss die ganze Jquery lernen, nur um ein Popup auf meiner Seite erscheinen zu lassen ... Ich kann den Return on Investment nicht sehen :( Gibt es eine einfachere Alternative? :( Nochmals vielen Dank für Ihre Antwort.
David D.
5
@ DavidW. Hallo David, ich bin froh, dass meine Antwort dir geholfen hat. AJAX ist eine Technik, die Sie mit einfachem Javascript ausführen können, die jedoch sehr kompliziert werden kann. jQuery hat einfach Verknüpfungen, die es viel einfacher machen. Es hat nichts mit dem Modal von Bootstrap zu tun (Sie können Formulare über AJAX abrufen, wenn Sie möchten, aber es hat ansonsten nichts damit zu tun). Wie auch immer, ich schlage vor, Sie versuchen, sich langsam zurechtzufinden. jQuery ist heutzutage wichtig und sehr einfach, also gute Investition dort. Wenn Sie auf eine Straßensperre stoßen, kommen Sie zu SO und fragen Sie (nicht hier in den Kommentaren einer bereits beantworteten Frage, öffnen Sie eine neue). Viel Glück!
Yuvi
Können csrf_tokenwir diese Methode in Bezug auf Ihre Erwähnung umgehen? Wenn wir eine Beispielfunktion hätten ajaxCall(), könnten wir einfach die traditionelle Methode von so etwas verwenden <form onsubmit='ajaxCall();return false;'>, oder?
Ytpillai
22

Neben der hervorragenden Antwort von yuvi möchte ich ein kleines spezifisches Beispiel hinzufügen, wie man damit in Django umgeht (über alle js hinaus, die verwendet werden). In diesem Beispiel wird AjaxableResponseMixinein Autorenmodell verwendet und angenommen.

import json

from django.http import HttpResponse
from django.views.generic.edit import CreateView
from myapp.models import Author

class AjaxableResponseMixin(object):
    """
    Mixin to add AJAX support to a form.
    Must be used with an object-based FormView (e.g. CreateView)
    """
    def render_to_json_response(self, context, **response_kwargs):
        data = json.dumps(context)
        response_kwargs['content_type'] = 'application/json'
        return HttpResponse(data, **response_kwargs)

    def form_invalid(self, form):
        response = super(AjaxableResponseMixin, self).form_invalid(form)
        if self.request.is_ajax():
            return self.render_to_json_response(form.errors, status=400)
        else:
            return response

    def form_valid(self, form):
        # We make sure to call the parent's form_valid() method because
        # it might do some processing (in the case of CreateView, it will
        # call form.save() for example).
        response = super(AjaxableResponseMixin, self).form_valid(form)
        if self.request.is_ajax():
            data = {
                'pk': self.object.pk,
            }
            return self.render_to_json_response(data)
        else:
            return response

class AuthorCreate(AjaxableResponseMixin, CreateView):
    model = Author
    fields = ['name']

Quelle: Django-Dokumentation, Formularverarbeitung mit klassenbasierten Ansichten

Der Link zu Version 1.6 von Django ist nicht mehr verfügbar und wurde auf Version 1.11 aktualisiert

Wtower
quelle
14

Ich schreibe dies, weil die akzeptierte Antwort ziemlich alt ist und eine Auffrischung benötigt.

So würde ich Ajax 2019 in Django integrieren :) Und nehmen wir ein echtes Beispiel dafür, wann wir Ajax brauchen würden:

Nehmen wir an, ich habe ein Modell mit registrierten Benutzernamen und mit Hilfe von Ajax möchte ich wissen, ob ein bestimmter Benutzername vorhanden ist.

html:

<p id="response_msg"></p> 
<form id="username_exists_form" method='GET'>
      Name: <input type="username" name="username" />
      <button type='submit'> Check </button>           
</form>   

Ajax:

$('#username_exists_form').on('submit',function(e){
    e.preventDefault();
    var username = $(this).find('input').val();
    $.get('/exists/',
          {'username': username},   
          function(response){ $('#response_msg').text(response.msg); }
    );
}); 

urls.py:

from django.contrib import admin
from django.urls import path
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('exists/', views.username_exists, name='exists'),
]

views.py:

def username_exists(request):
    data = {'msg':''}   
    if request.method == 'GET':
        username = request.GET.get('username').lower()
        exists = Usernames.objects.filter(name=username).exists()
        if exists:
            data['msg'] = username + ' already exists.'
        else:
            data['msg'] = username + ' does not exists.'
    return JsonResponse(data)

Auch render_to_response, das veraltet ist und durch render ersetzt wurde , und ab Django 1.7 anstelle von HttpResponse verwenden wir JsonResponse für die Ajax- Antwort. Da es mit einem JSON-Encoder geliefert wird, müssen Sie die Daten nicht serialisieren, bevor Sie das Antwortobjekt zurückgeben, es HttpResponseist jedoch nicht veraltet.

Ahtisham
quelle
8

Einfach und nett. Sie müssen Ihre Ansichten nicht ändern. Bjax kümmert sich um alle Ihre Links. Schauen Sie sich das an: Bjax

Verwendungszweck:

<script src="bjax.min.js" type="text/javascript"></script>
<link href="bjax.min.css" rel="stylesheet" type="text/css" />

Fügen Sie dies schließlich in den KOPF Ihres HTML-Codes ein:

$('a').bjax();

Weitere Einstellungen finden Sie hier in der Demo: Bjax Demo

ertragen
quelle
18
Hallo, kurze Anmerkung - Ich will jemanden raten , die gerade beginnt , Django zu lernen und \ oder AJAX - bitte nicht diesen verwenden. Du wirst nichts lernen. Behalten Sie es in Ihren Favoriten und erstellen Sie Ihre AJAX-Anfragen selbst. Kommen Sie zurück und verwenden Sie Bjax, sobald Sie bereits mit der Funktionsweise im Hintergrund vertraut sind. Dies ist nicht so, als würde man den Leuten sagen, dass sie Assembly lernen sollen, um zu programmieren. Sie müssen Ihre AJAX-Anforderungen nicht mit reinem JS erstellen, sondern nur mit jQuery. Wenn Sie jemals ein Profi sein möchten, ist dies das Mindestgrundwissen, das Sie benötigen haben müssen. Prost
yuvi
5

AJAX ist der beste Weg, um asynchrone Aufgaben auszuführen. Das Tätigen von asynchronen Anrufen wird häufig bei der Erstellung von Websites verwendet. Wir werden ein kurzes Beispiel nehmen, um zu erfahren, wie wir AJAX in Django implementieren können. Wir müssen jQuery verwenden, um weniger Javascript zu schreiben.

Dies ist das Kontaktbeispiel. Dies ist das einfachste Beispiel, mit dem ich die Grundlagen von AJAX und seine Implementierung in Django erläutere. In diesem Beispiel stellen wir eine POST-Anfrage. Ich folge einem Beispiel dieses Beitrags: https://djangopy.org/learn/step-up-guide-to-implement-ajax-in-django

models.py

Lassen Sie uns zunächst das Kontaktmodell mit grundlegenden Details erstellen.

from django.db import models

class Contact(models.Model):
    name = models.CharField(max_length = 100)
    email = models.EmailField()
    message = models.TextField()
    timestamp = models.DateTimeField(auto_now_add = True)

    def __str__(self):
        return self.name

forms.py

Erstellen Sie das Formular für das obige Modell.

from django import forms
from .models import Contact

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        exclude = ["timestamp", ]

views.py

Die Ansichten ähneln der grundlegenden funktionsbasierten Erstellungsansicht, aber anstatt mit dem Rendern zurückzukehren, verwenden wir die JsonResponse-Antwort.

from django.http import JsonResponse
from .forms import ContactForm

def postContact(request):
    if request.method == "POST" and request.is_ajax():
        form = ContactForm(request.POST)
        form.save()
        return JsonResponse({"success":True}, status=200)
    return JsonResponse({"success":False}, status=400)

urls.py

Lassen Sie uns die Route der obigen Ansicht erstellen.

from django.contrib import admin
from django.urls import path
from app_1 import views as app1

urlpatterns = [
    path('ajax/contact', app1.postContact, name ='contact_submit'),
]

Vorlage

Wenn Sie zum Frontend-Bereich wechseln, rendern Sie das Formular, das über dem Formular-Tag erstellt wurde, zusammen mit csrf_token und der Schaltfläche "Senden". Beachten Sie, dass wir die jquery-Bibliothek aufgenommen haben.

<form id = "contactForm" method= "POST">{% csrf_token %}
   {{ contactForm.as_p }}
  <input type="submit" name="contact-submit" class="btn btn-primary" />
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Javascript

Lassen Sie uns nun über den Javascript-Teil sprechen. Auf dem Formular senden wir eine Ajax-Anfrage vom Typ POST, nehmen die Formulardaten und senden sie an den Server.

$("#contactForm").submit(function(e){
    // prevent from normal form behaviour
        e.preventDefault();
        // serialize the form data  
        var serializedData = $(this).serialize();
        $.ajax({
            type : 'POST',
            url :  "{% url 'contact_submit' %}",
            data : serializedData,
            success : function(response){
            //reset the form after successful submit
                $("#contactForm")[0].reset(); 
            },
            error : function(response){
                console.log(response)
            }
        });
   });

Dies ist nur ein einfaches Beispiel für den Einstieg in AJAX mit Django. Wenn Sie mit mehreren weiteren Beispielen tauchen möchten, lesen Sie diesen Artikel: https://djangopy.org/learn/step-up-guide-to- Implementiere-Ajax-in-Django

Jai Singhal
quelle
2

Ich habe versucht, AjaxableResponseMixin in meinem Projekt zu verwenden, hatte jedoch die folgende Fehlermeldung erhalten:

Unsachgemäß konfiguriert: Keine URL zum Weiterleiten. Geben Sie entweder eine URL an oder definieren Sie eine get_absolute_url-Methode für das Modell.

Dies liegt daran, dass CreateView eine Umleitungsantwort zurückgibt, anstatt eine HttpResponse zurückzugeben, wenn Sie eine JSON-Anforderung an den Browser senden. Also habe ich einige Änderungen an der vorgenommen AjaxableResponseMixin. Wenn es sich bei der Anforderung um eine Ajax-Anforderung handelt, wird die super.form_validMethode nicht aufgerufen, sondern nur form.save()direkt.

from django.http import JsonResponse
from django import forms
from django.db import models

class AjaxableResponseMixin(object):
    success_return_code = 1
    error_return_code = 0
    """
    Mixin to add AJAX support to a form.
    Must be used with an object-based FormView (e.g. CreateView)
    """
    def form_invalid(self, form):
        response = super(AjaxableResponseMixin, self).form_invalid(form)
        if self.request.is_ajax():
            form.errors.update({'result': self.error_return_code})
            return JsonResponse(form.errors, status=400)
        else:
            return response

    def form_valid(self, form):
        # We make sure to call the parent's form_valid() method because
        # it might do some processing (in the case of CreateView, it will
        # call form.save() for example).
        if self.request.is_ajax():
            self.object = form.save()
            data = {
                'result': self.success_return_code
            }
            return JsonResponse(data)
        else:
            response = super(AjaxableResponseMixin, self).form_valid(form)
            return response

class Product(models.Model):
    name = models.CharField('product name', max_length=255)

class ProductAddForm(forms.ModelForm):
    '''
    Product add form
    '''
    class Meta:
        model = Product
        exclude = ['id']


class PriceUnitAddView(AjaxableResponseMixin, CreateView):
    '''
    Product add view
    '''
    model = Product
    form_class = ProductAddForm
Enix
quelle
0

Wenn wir Django verwenden:

Server ===> Client(Browser)   
      Send a page

When you click button and send the form,
----------------------------
Server <=== Client(Browser)  
      Give data back. (data in form will be lost)
Server ===> Client(Browser)  
      Send a page after doing sth with these data
----------------------------

Wenn Sie alte Daten behalten möchten, können Sie dies ohne Ajax tun. (Seite wird aktualisiert)

Server ===> Client(Browser)   
      Send a page
Server <=== Client(Browser)  
      Give data back. (data in form will be lost)
Server ===> Client(Browser)  
      1. Send a page after doing sth with data
      2. Insert data into form and make it like before. 
      After these thing, server will send a html page to client. It means that server do more work, however, the way to work is same.

Oder Sie können mit Ajax tun (Seite wird nicht aktualisiert)

--------------------------
<Initialization> 
Server ===> Client(Browser) [from URL1]    
      Give a page                      
--------------------------  
<Communication>
Server <=== Client(Browser)     
      Give data struct back but not to refresh the page.
Server ===> Client(Browser) [from URL2] 
      Give a data struct(such as JSON)
---------------------------------

Wenn Sie Ajax verwenden, müssen Sie folgende Schritte ausführen:

  1. Initialisieren Sie eine HTML-Seite mit URL1 (normalerweise initialisieren Sie die Seite mit einer Django-Vorlage). Und dann Server Server Client eine HTML-Seite.
  2. Verwenden Sie Ajax, um über URL2 mit dem Server zu kommunizieren. Und dann sendet der Server dem Client eine Datenstruktur.

Django unterscheidet sich von Ajax. Der Grund dafür ist folgender:

  • Die Sache, die zum Kunden zurückkehrt, ist anders. Der Fall von Django ist eine HTML-Seite. Der Fall von Ajax ist Datenstruktur. 
  • Django ist gut darin, etwas zu erschaffen, aber es kann nur einmal erschaffen, es kann nichts ändern. Django ist wie Anime, besteht aus vielen Bildern. Im Gegensatz dazu kann Ajax nicht gut etwas erstellen, sondern etwas auf einer vorhandenen HTML-Seite ändern.

Meiner Meinung nach, wenn Sie Ajax überall verwenden möchten. Wenn Sie zuerst eine Seite mit Daten initialisieren müssen, können Sie Django mit Ajax verwenden. In einigen Fällen benötigen Sie jedoch nur eine statische Seite ohne Server. Sie müssen keine Django-Vorlage verwenden.

Wenn Sie nicht glauben, dass Ajax die beste Vorgehensweise ist. Sie können Django-Vorlage verwenden, um alles zu tun, wie Anime.

(Mein Englisch ist nicht gut)

Kyakya
quelle