Comment intégrer Ajax avec les applications Django?

Je suis nouveau sur Django et assez nouveau sur Ajax. Je travaille sur un projet où je dois intégrer les deux. Je crois que je comprends les principes derrière les deux, mais je n'ai pas trouvé une bonne explication des deux ensemble.

Quelqu'un pourrait-il me donner une explication rapide de la façon dont la base de code doit changer avec les deux d'entre eux s'intégrant ensemble?

Par exemple, puis-je toujours utiliser le HttpResponse avec Ajax, ou mes réponses doivent-elles changer avec L'utilisation D'Ajax? Si oui, pourriez-vous veuillez fournir un exemple de la façon dont les réponses aux demandes de changement? Si cela fait une différence, les données que je retourne sont JSON.

211
demandé sur George Stocker 2013-12-01 03:41:00

4 réponses

Même si ce n'est pas tout à fait dans L'esprit SO, j'aime cette question, parce que j'ai eu le même problème quand j'ai commencé alors je vais vous donner un guide rapide. Évidemment, vous ne comprenez pas les principes qui les sous-tendent (ne le prenez pas comme une infraction, mais si vous le faisiez, vous ne le demanderiez pas).

Django est Côté Serveur. Cela signifie, disons qu'un client va à l'url que vous avez une fonction dans les vues qui rend ce qu'il voit et renvoie une réponse en html. nous allons décomposer en exemples:

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'),

C'est un exemple des usages les plus simples. Aller à 127.0.0.1:8000/hello signifie une requête à la fonction hello, aller à {[5] } retournera le index.html et remplacera toutes les variables comme demandé (vous savez probablement tout cela maintenant).

Parlons maintenant de L'AJAX. Les appels AJAX sont du code côté client qui effectue des requêtes asynchrones. Cela semble compliqué, mais cela signifie simplement qu'il fait une demande de vous en arrière-plan, puis gère la réponse. Donc, quand vous faites un appel AJAX pour une url, vous obtenez les mêmes données que vous obtiendriez en tant qu'utilisateur allant à cet endroit.

Par exemple, un appel ajax à 127.0.0.1:8000/hello renverra la même chose que si vous l'aviez visité. Seulement cette fois, vous l'avez dans une fonction js et vous pouvez le gérer comme vous le souhaitez. Regardons un cas d'utilisation simple:

$.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');
    }
}); 

Le processus général est le suivant:

  1. L'appel à l'url 127.0.0.1:8000/hello comme si vous avez ouvert un nouvel onglet et l'avez fait vous-même.
  2. si elle réussit (code d'état 200), faites la fonction pour réussir, qui alertera les données reçues.
  3. si échoue, effectuez une fonction différente.

Maintenant ce qui allait se passer ici? Vous obtiendriez une alerte avec "hello world" dedans. Qu'advient-il si vous faites un appel ajax à la maison? Même chose, vous recevrez une alerte indiquant <h1>Hello world, welcome to my awesome site</h1>.

En d'autres termes - il n'y a rien de nouveau sur les appels AJAX. Ils sont juste un moyen pour vous laisser le utilisateur obtenir des données et des informations sans quitter la page, et il fait pour une conception lisse et très soignée de votre site web. Quelques lignes directrices que vous devriez prendre note de:

  1. Apprendre jQuery. Je ne peux pas insister assez sur ce point. Vous allez devoir le comprendre un peu pour savoir comment gérer les données que vous recevez. Vous aurez également besoin de comprendre une syntaxe javascript de base (non loin de python, vous vous y habituerez). Je recommande fortement les tutoriels vidéo de Envato pour jQuery , ils sont grands et vous mettre sur le bon chemin.
  2. Quand utiliser JSON?. Vous allez voir beaucoup d'exemples où les données envoyées par les vues Django sont en JSON. Je ne suis pas entré dans les détails à ce sujet, parce que ce n'est pas important Comment le faire (il y a beaucoup d'explications abondent) et beaucoup plus important quand. Et la réponse à cela est-les données JSON sont des données sérialisées. Autrement dit, les données que vous pouvez manipuler. Comme je l'ai mentionné, un appel AJAX sera chercher la réponse comme si l'utilisateur fait lui-même. Maintenant, dites que vous ne voulez pas jouer avec tout le html, et que vous voulez plutôt envoyer des données (une liste d'objets peut-être). JSON est bon pour cela, car il l'envoie en tant qu'objet (les données JSON ressemblent à un dictionnaire python), puis vous pouvez itérer dessus ou faire autre chose qui supprime le besoin de passer au crible le html inutile.
  3. ajoutez-le en dernier . Lorsque vous construisez une application web et que vous voulez implémenter AJAX-faites-vous une faveur. Tout d'abord, construire le application entière complètement dépourvue de tout AJAX. Voir que tout fonctionne. Ensuite, et seulement alors, commencez à écrire les appels AJAX. C'est un bon processus qui vous aide à apprendre beaucoup aussi.
  4. utilisez les outils de développement de chrome . Puisque les appels AJAX sont effectués en arrière-plan, il est parfois très difficile de les déboguer. Vous devez utiliser les outils de développement chrome (ou des outils similaires tels que firebug) et console.log choses à déboguer. Je ne vais pas expliquer en détail, juste google autour et savoir à ce sujet. Il serait très utile pour vous.
  5. sensibilisation CSRF . Enfin, rappelez-vous que les requêtes post dans Django nécessitent le csrf_token. Avec les appels AJAX, vous souhaitez souvent envoyer des données sans rafraîchir la page. Vous aurez probablement des problèmes avant de vous en souvenir-attendez, vous avez oublié d'envoyer le csrf_token. Ceci est un barrage routier débutant connu dans L'intégration AJAX-Django, mais après avoir appris à le faire jouer bien, c'est facile comme tarte.

C'est tout qui vient à ma tête. C'est un vaste sujet, mais oui, il n'y a probablement pas assez d'exemples. Il suffit de travailler votre chemin là-bas, lentement, vous aurez finalement.

549
répondu yuvi 2015-12-26 01:35:40

Plus loin de l'excellente réponse de yuvi, je voudrais ajouter un petit exemple spécifique sur la façon de traiter cela dans Django (au-delà de tout js qui sera utilisé). L'exemple utilise AjaxableResponseMixin et suppose un modèle D'auteur.

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']

Source: Documentation Django, gestion des formulaires avec des vues basées sur des classes

Le lien vers la version 1.6 de Django n'est plus disponible en version 1.11

17
répondu Wtower 2018-02-03 18:52:12

Simple et agréable. Vous n'avez pas à changer votre point de vue. Bjax gère tous vos liens. Check this out: Bjax

Utilisation:

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

Enfin, incluez ceci dans la tête de votre html:

$('a').bjax();

Pour plus de paramètres, commander la démo ici: Bjax Démo

7
répondu endur 2015-11-24 01:37:10

J'ai essayé d'utiliser AjaxableResponseMixin dans mon projet, mais a fini avec le message d'erreur suivant:

ImproperlyConfigured: aucune URL vers laquelle rediriger. Fournissez une url ou définissez une méthode get_absolute_url sur le modèle.

C'est parce que CreateView retournera une réponse de redirection au lieu de renvoyer une réponse HttpResponse lorsque vous envoyez une requête JSON au navigateur. J'ai donc apporté quelques modifications au AjaxableResponseMixin. Si la demande est une ajax request, il n'appellera pas la méthode super.form_valid, Il suffit d'appeler le form.save() directement.

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
2
répondu Enix 2017-11-15 01:29:18