53 votes

URL sèches dans Javascript Django

J'utilise Django sur Appengine. J'utilise la fonction reverse() django partout, tout en maintenant le plus sec possible.

Cependant, j'ai du mal à l'appliquer à mon javascript côté client. Il existe une classe JS qui charge certaines données en fonction d'un ID transmis. Existe-t-il un moyen standard de ne pas coder en dur l'URL à partir de laquelle ces données devraient provenir?

 var rq = new Request.HTML({
    'update':this.element,
}).get('/template/'+template_id+'/preview'); //The part that bothers me.
 

34voto

Anatoly Rr Points 551

Il existe une autre méthode, qui n'exige pas d'exposer la structure entière de l'URL ou les demandes ajax pour résoudre chaque URL. Bien que ce ne soit pas vraiment beau, il bat les autres avec simplicité:

 var url = '{% url blog_view_post 999 %}'.replace (999, post_id);
 

( blog_view_post urls ne doivent pas contenir le nombre magique 999 bien sûr.)

9voto

Noio Points 1713

La solution la plus raisonnable semble être de passer une liste d'URL dans un fichier JavaScript et d'avoir un équivalent JavaScript de reverse () disponible sur le client. La seule objection peut être que toute la structure de l'URL est exposée.

Voici une telle fonction (de cette question ).

6voto

T. Stone Points 10782

Oui cela m'énerve trop.

Il y a du javascript-rendu-avec-Django-modèle de langue de la méthode est similaire à ce que vous avez affichée ci-dessus, cependant, j'ai trouvé assez rapidement que cela peut facilement devenir trop encombrant lorsque le javascript est stockée dans un fichier externe.

Il y a probablement de nombreuses façons de s'attaquer à ce problème, mais j'ai créé un simple helper app pour permettre la résolution d'url via AJAX. Il y a deux parties 2 parties -- le côté serveur l'url de la vue qui renvoie la valeur et le script côté client, qui fournit l'accès.

Il semble plus facile qu'elle ne l'est en réalité. Vous aurez souvent envie de passer des arguments dans l' resolve fonction et souvent de l'ordre de ces arguments est très important. Pour maintenir l'ordre, lorsque je passe les arguments de retour de Django, je les orienter dans la chaîne de requête avec à la clé le n ° de leur ordre.

Une fois inclus (le javascript dépend de jQuery), vous pouvez y accéder avec...

// Equivalent to {% url blog_view_post post_id %}
var url = Django.reverse('blog_view_post', [post_id] );

Sur le côté serveur...

javascript/views.py

from django.http import HttpResponse
from django.core.urlresolvers import reverse


def reverse_url(request, url_name):

    # Turn querystring into an array of couplets (2x list)
    # arg_couplets = [ ('key', 'value'), ('key', 'value') ]
    arg_couplets = request.REQUEST.items()

    # Sort by keys
    arg_couplets.sort(lambda x,y: cmp(x[0], y[0]))

    # Collapse list into just the values
    args = [c[1] for c in arg_couplets]

    try:
        if args:
            return HttpResponse(reverse(url_name, args=args))
        else:
            return HttpResponse(reverse(url_name))
    except:
        return HttpResponse()

Sur le côté client... (assurez-vous d'inclure dans votre modèle)

/media/django-javascript.js

(function($) {

    Django = function() {
        return {
            reverse: function(name, args) {
                var ret;
                var arguments = {};
                var c = 0;

                // Convert args to keyed dictionary
                for (i in args) {
                    arguments[c] = args[i];
                    c++;
                }

                $.ajax({
                    async: false,
                    url: '/javascript/reverse/' + name + '/',
                    data: arguments,
                    success: function(html) {
                        ret = html;
                    }
                });

                if (ret.length > 0) {
                    return ret;
                }
                else {
                    return null;
                }

            }
        }
    }();

})(jQuery);

Sur une note de côté, j'ai aussi fait ça pour MEDIA_URL et certains autres souvent utilisé les paramètres.

4voto

Tomasz Wysocki Points 4392

La bonne chose est de supposer que tous les paramètres de JavaScript à Django seront passés en tant que request.GET ou request.POST. Vous pouvez le faire dans la plupart des cas, car vous n'avez pas besoin de belles URL formatées pour les requêtes JavaScript.

Ensuite, le seul problème est de passer l’URL de Django à JavaScript. J'ai publié la bibliothèque pour cela. Exemple de code:

urls.py

 def javascript_settings():
    return {
        'template_preview_url': reverse('template-preview'),
    }
 

javascript

 $.ajax({
  type: 'POST',
  url: configuration['my_rendering_app']['template_preview_url'],
  data: { template: 'foo.html' },
});
 

4voto

Hilton Shumway Points 76

Semblable à la réponse d'Anatoly, mais un peu plus souple. Mettez en haut de la page:

 <script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>
 

Ensuite, vous pouvez faire quelque chose comme

 url = window.myviewURL.replace('foobar','my_id';
 

ou peu importe. Si votre URL contient plusieurs variables, exécutez la méthode replace plusieurs fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X