最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Django: reverse parametrized url in JavaScript - Stack Overflow

programmeradmin3浏览0评论

let's say one of my urlpatterns looks like this.

url('^objects/update/(?P<pk>\d+)$', views.UpdateView.as_view(), name = 'update-object'),

I need to redirect user to the update page depending on the selected object (the list of objects is populated using Ajax). So I'd like to pass that named url pattern to the JavaScript, in order to build the actual url on the client side.

Example of what I want to achieve:

  1. pass the name 'update-objects' to the function
  2. get the actual url pattern, replace (?P<pk>..) with {pk}
  3. pass the result to the javascript, resulting in : objects/update/{pk}

any tips? thanks


to make it more clear: at the moment of rendering, I can't do url reverse because the PK is not known yet. I need to make kind of javascript-urlpattern which will later be converted to the real url (i.e. my JS code will replace {pk} part with the actual pk value)

let's say one of my urlpatterns looks like this.

url('^objects/update/(?P<pk>\d+)$', views.UpdateView.as_view(), name = 'update-object'),

I need to redirect user to the update page depending on the selected object (the list of objects is populated using Ajax). So I'd like to pass that named url pattern to the JavaScript, in order to build the actual url on the client side.

Example of what I want to achieve:

  1. pass the name 'update-objects' to the function
  2. get the actual url pattern, replace (?P<pk>..) with {pk}
  3. pass the result to the javascript, resulting in : objects/update/{pk}

any tips? thanks


to make it more clear: at the moment of rendering, I can't do url reverse because the PK is not known yet. I need to make kind of javascript-urlpattern which will later be converted to the real url (i.e. my JS code will replace {pk} part with the actual pk value)

Share Improve this question edited Jan 30, 2013 at 17:36 migajek asked Jan 30, 2013 at 15:09 migajekmigajek 8,61216 gold badges78 silver badges117 bronze badges 2
  • Perhaps I am misunderstanding the question, but why not just translate objects/update/(?P<pk>\d to something like objects/update/?pk? and let the client-side js figure out how to replace ?pk?. What you need to do in that case is just fool django's url reverse with some dummy values that match the regex, replace the dummy with ?pk? (or similar) and then store url template in a js variable somewhere. This remark is less aimed at the OP than at the other answers. Actually, instead of ?pk?, could use a marker that plays well with sprintf.js. – JL Peyret Commented Oct 23, 2015 at 2:06
  • Does this answer your question? Calling Django reverse in client-side Javascript – Flimm Commented Nov 24, 2020 at 8:18
Add a ment  | 

4 Answers 4

Reset to default 5

The actual URL reversing must happen on the server side. There are several ways to do this, and the most elegant of these probably depends on how exactly your script and markup are set up for this. One thing I've done recently is to attach the URL to a logical element using HTML5 data attributes, which are easy to retrieve using jQuery. If you're not using jQuery, I'll leave it up to you to translate to pure JS. You haven't provided any code or specifics for your client-side, so I'm kind of shooting in the dark here, but maybe this will give you the idea:

Django HTML template:

<ul class="object-list">
 {% for object in objectList %}
  <li data-update-url="{% url update-objects object.pk %}">object.name</li>
 {% endfor %}
</ul>

JS:

$('.object-list').on('click', 'li' function () {
  var updateUrl = $(this).data('update-url')
  ...
});

It sounds like you need to make an additional ajax call once the object has actually been selected. Don't try and second guess your url.conf by trying to work out the url on the client side - you'd just be making trouble for yourself later. Wait till you can get a pk, then use django's reverse function to give you your url (doing anything else violates DRY).

How about creating a simple view that returns the url -

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

def get_url(request):
    if request.is_ajax() and request.method == 'POST':
        obj_id = request.POST['obj_id']
        url = reverse('object-update', kwargs{'pk': obj_id})
        return HttpResponse(obj_id)
    return HttpResponseBadRequest()

Then write a javascript function that gets the url using an ajax call to your new view and then redirects. You'd call this function as soon as the object's been selected. I would suggest using JQuery to do this, pure javascript will require you to write more code, and probably write browser specific code (depending on your target). Also it supports dealing with django's csrf protection (you'll need to implement this for ajax calls if you haven't already).

var redirect = function(obj) {
    $.ajax({
        url: '/your-get-url-view/',
        method: 'post',
        data: {'obj_id': obj},
        success: function(url){
            window.location = url;
        }
    });
}

I'm afraid I don't know how you're getting from the selected object to the pk (For simplicity I've assumed it's available to the redirect function) - you may have to do some processing in the view to get there.

I haven't tested the above code, but it should give you an idea of what I'm suggesting.

Try this one:

Reverse method for generating Django urls
https://github./mlouro/django-js-utils

One more
https://github./Dimitri-Gnidash/django-js-utils

If you have a URL that only has one PK field in it, you could resolve it with any number (e.g. 0), then substitute the number as required.

In my scenario my URL had a pk then an upload_id, so I had to replace on the right most instance of a 0, with <upload_id>, which the JS would replace this string occurance as required:

detele_url_upload_id_0 = reverse(f'{APP_NAME}:api_upload_delete', args=[pk, 0])
prefix, suffix = detele_url_upload_id_0.rsplit('0', 1)
context['generic_delete_url'] = prefix + '<upload_id>' + suffix

Then in the JS:

const deleteUrl = genericDeleteUrl.replace('<upload_id>', uploadId)
发布评论

评论列表(0)

  1. 暂无评论