web-dev-qa-db-fra.com

Rendu d'objets JSON à l'aide d'un modèle Django après un appel Ajax

J'ai essayé de comprendre quelle est la meilleure façon de faire Ajax in Django . En lisant des trucs ici et là, j'ai compris que le processus commun est:

  1. formulez votre appel Ajax en utilisant une bibliothèque JavaScript (par exemple jQuery ), configurez un modèle d'URL dans Django qui intercepte l'appel et passe à une fonction de vue

  2. dans la fonction de vue Python récupérer les objets qui vous intéressent et les renvoyer au client au format JSON ou similaire (en utilisant le module sérialiseur intégré, ou simplejson )

  3. définir une fonction de rappel en JavaScript qui reçoit les données JSON et les analyse, afin de créer le code HTML à afficher. Enfin, le script JavaScript place le HTML où il devrait rester.

Maintenant, ce que je ne comprends toujours pas, c'est comment sont les modèles Django liés à tout cela? Apparemment, nous n'utilisons pas la puissance de modèles du tout. Idéalement, je pensais que ce serait bien de renvoyer un objet JSON et un nom de modèle, afin que les données puissent être itérées et qu'un bloc HTML soit créé. Mais peut-être que je me trompe totalement ici ...

La seule ressource que j'ai trouvée qui va dans ce sens est cet extrait (769) mais je ne l'ai pas encore essayé. De toute évidence, ce qui va se passer dans ce cas, c'est que tout le code HTML résultant est créé côté serveur, puis transmis au client. La fonction de rappel JavaScript n'a qu'à l'afficher au bon endroit.

Est-ce que cela cause des problèmes de performances? Sinon, même sans utiliser l'extrait ci-dessus, pourquoi ne pas formater le HTML directement dans le backend en utilisant Python au lieu du front-end?

Merci beaucoup!

MISE À JOUR: veuillez utiliser extrait 942 car il s'agit d'une version améliorée de celle ci-dessus! J'ai trouvé que le support d'héritage fonctionne beaucoup mieux de cette façon ..

65
magicrebirth

Salut merci vikingosegundo!

J'aime aussi utiliser les décorateurs :-). Mais en attendant, j'ai suivi l'approche suggérée par l'extrait de code que je mentionnais ci-dessus. Seule chose, utilisez plutôt l'extrait n. 942 car c'est une version améliorée de l'original. Voici comment ça fonctionne:

Imaginez que vous disposez d'un modèle (par exemple, `` subtemplate.html '') de n'importe quelle taille qui contient un bloc utile que vous pouvez réutiliser:

     ........
    <div id="results">          
        {% block results %}
            {% for el in items %}
                   <li>{{el|capfirst}}</li>
            {% endfor %}
        {% endblock %}      
    </div><br />
     ........

En important dans votre fichier de vue l'extrait ci-dessus, vous pouvez facilement faire référence à n'importe quel bloc dans vos modèles. Une fonctionnalité intéressante est que les relations d'héritage entre les modèles sont prises en compte, donc si vous faites référence à un bloc qui inclut un autre bloc, etc., tout devrait fonctionner correctement. Ainsi, la vue ajax ressemble à ceci:

from Django.template import loader
# downloaded from djangosnippets.com[942]
from my_project.snippets.template import render_block_to_string

def ajax_view(request):
    # some random context
    context = Context({'items': range(100)})
    # passing the template_name + block_name + context
    return_str = render_block_to_string('standard/subtemplate.html', 'results', context)
    return HttpResponse(return_str)
25
magicrebirth

Voici comment j'utilise le même modèle pour le rendu traditionnel et le rendu à réponse Ajax.

Modèle:

<div  id="sortable">

{% include "admin/app/model/subtemplate.html" %}
</div>

Modèle inclus (aka: sous-modèle):

<div id="results_listing">
{% if results %}
    {% for c in results %}
        .....
    {% endfor %}
{% else %}

La vue Ajax:

@login_required
@render_to('admin/app/model/subtemplate.html')#annoying-decorator
def ajax_view(request):
    .....

    return { 
        "results":Model.objects.all(),
    }      

Bien sûr, vous pouvez utiliser render_to_response. Mais j'aime ces décorateurs ennuyeux: D

13
vikingosegundo

Il n'y a aucune raison pour laquelle vous ne pouvez pas renvoyer un bit HTML rendu à l'aide d'Ajax et l'insérer dans la page existante à l'endroit souhaité. Évidemment, vous pouvez utiliser les modèles de Django pour rendre ce HTML, si vous le souhaitez.

7
Daniel Roseman

Lorsque vous faites Ajax, je ne pense pas que vous ayez une quelconque utilité pour les modèles. Le modèle est là pour que vous puissiez générer facilement du HTML dynamique côté serveur et donc il fournit peu de crochets de programmation à l'intérieur du HTML.

Dans le cas d'Ajax, vous transmettez des données JSON et vous pouvez les formater comme vous le souhaitez en Python. et les éléments HTML/document seront générés côté client à l'aide du JSON par une bibliothèque JavaScript, par exemple jQuery côté client.

Peut-être que si vous avez un cas très spécifique de remplacement du HTML interne du HTML côté serveur, vous pouvez peut-être utiliser des modèles, mais dans ce cas, pourquoi auriez-vous besoin de JSON? Vous pouvez simplement interroger la page HTML via Ajax et modifier le HTML interne ou externe ou tout autre HTML.

6
Anurag Uniyal

Les modèles sont destinés à la présentation . Répondre avec des données au format X (JSON, JSONP , XML, YAML , * ml, etc.) n'est pas une présentation, vous n'avez donc pas besoin de modèles. Sérialisez simplement vos données au format X et renvoyez-les dans une HttpResponse.

3
yfeldblum

Bien que les modèles ne soient en effet qu'à des fins de présentation, peu importe que vous le fassiez côté serveur ou côté client. Tout se résume à séparer la logique de contrôle qui exécute une action de la logique de vue qui est juste responsable de la création du balisage. Si votre logique de contrôle javascript doit gérer la façon dont vous effectuez le rendu ou l'affichage du code HTML, vous pouvez le faire de manière incorrecte, mais si vous isolez cette logique de rendu vers un autre objet ou fonction, et lui transmettez simplement les données nécessaires au rendu, Ensuite ça devrait aller; il reflète la façon dont nous séparons nos contrôleurs, modèles et vues côté serveur.

Jetez un œil au projet github: http://github.com/comolongo/Yz-Javascript-Django-Template-Compiler

Il compile Django modèles en fonctions javascript optimisées qui généreront votre présentation html avec les données que vous lui transmettez. Les fonctions compilées sont en javascript pur, donc il n'y a pas de dépendances sur d'autres bibliothèques. Puisque les modèles sont compilés au lieu d'être analysés au moment de l'exécution, les chaînes et les variables sont déjà toutes placées dans des chaînes javascript qui doivent juste être concaténées, donc vous obtenez un énorme augmentation de la vitesse par rapport aux techniques qui nécessitent que vous fassiez une manipulation dom ou une analyse de script pour obtenir la présentation finale. À l'heure actuelle, seuls les balises et les filtres de base sont là, mais devraient suffire pour la plupart des choses, et plus de balises seront ajoutées au fur et à mesure que les gens commenceront à créer demandes ou commencez à contribuer au projet.

3
Weiss I Nicht

Vous pouvez utiliser jquery.load() ou similaire, générer le code HTML sur le serveur et le charger dans le DOM avec JavaScript. Je pense que quelqu'un a appelé cela AJAH .

1
Skylar Saveland

Malheureusement, Django sont conçus pour être exécutés côté serveur uniquement. Il y a au moins un projet à rendre Django utilisant Javascript , mais je ne l'ai pas utilisé et je ne sais donc pas à quel point il est rapide, bien pris en charge ou à jour. À part cela, vous devez soit utiliser les modèles Django sur le serveur ou générer des éléments dynamiques sur le client sans utiliser de modèles.

0
Casebash