9
35
There is another method, which doesn’t require exposing the entire url structure or ajax requests for resolving each url. While it’s not really beautiful, it beats the others with simplicity:
var url = '{% url blog_view_post 999 %}'.replace (999, post_id);
(blog_view_post
urls must not contain the magic 999
number themselves of course.)
- [Django]-Disable migrations when running unit tests in Django 1.7
- [Django]-How to upgrade django?
- [Django]-How do you convert a PIL `Image` to a Django `File`?
13
Having just struggled with this, I came up with a slightly different solution.
In my case, I wanted an external JS script to invoke an AJAX call on a button click (after doing some other processing).
In the HTML, I used an HTML-5 custom attribute thus
<button ... id="test-button" data-ajax-target="{% url 'named-url' %}">
Then, in the javascript, simply did
$.post($("#test-button").attr("data-ajax-target"), ... );
Which meant Django’s template system did all the reverse()
logic for me.
- [Django]-Django DateField default options
- [Django]-Optimal architecture for multitenant application on django
- [Django]-Sending an SMS to a Cellphone using Django
4
Good thing is to assume that all parameters from JavaScript to Django will be passed as request.GET or request.POST. You can do that in most cases, because you don’t need nice formatted urls for JavaScript queries.
Then only problem is to pass url from Django to JavaScript. I have published library for that. Example 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' },
});
- [Django]-Cannot import name patterns
- [Django]-Django Password Generator
- [Django]-How to do SELECT MAX in Django?
4
Similar to Anatoly’s answer, but a little more flexible. Put at the top of the page:
<script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>
Then you can do something like
url = window.myviewURL.replace('foobar','my_id');
or whatever. If your url contains multiple variables just run the replace method multiple times.
- [Django]-How to disable Django's invalid HTTP_HOST error?
- [Django]-Django models: get list of id
- [Django]-Django-social-auth django-registration and django-profiles — together
2
I like Anatoly’s idea, but I think using a specific integer is dangerous. I typically want to specify an say an object id, which are always required to be positive, so I just use negative integers as placeholders. This means adding -?
to the the url definition, like so:
url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details),
Then I can get the reverse url in a template by writing
{% url 'events.views.event_details' event_id=-1 %}
And use replace
in javascript to replace the placeholder -1
, so that in the template I would write something like
<script type="text/javascript">
var actual_event_id = 123;
var url = "{% url 'events.views.event_details' event_id=-1 %}".replace('-1', actual_event_id);
</script>
This easily extends to multiple arguments too, and the mapping for a particular argument is visible directly in the template.
- [Django]-Whats the difference between a OneToOne, ManyToMany, and a ForeignKey Field in Django?
- [Django]-How can I see the raw SQL queries Django is running?
- [Django]-How can I obtain the model's name or the content type of a Django object?
1
I’ve found a simple trick for this. If your url is a pattern like:
"xyz/(?P<stuff>.*)$"
and you want to reverse in the JS without actually providing stuff (deferring to the JS run time to provide this) – you can do the following:
Alter the view to give the parameter a default value – of none, and handle that by responding with an error if its not set:
views.py
def xzy(stuff=None):
if not stuff:
raise Http404
... < rest of the view code> ...
- Alter the URL match to make the parameter optional:
"xyz/(?P<stuff>.*)?$"
-
And in the template js code:
.ajax({
url: “{{ url views.xyz }}” + js_stuff,
… …
})
The generated template should then have the URL without the parameter in the JS, and in the JS you can simply concatenate on the parameter(s).
- [Django]-How can I resolve 'django_content_type already exists'?
- [Django]-Django most efficient way to count same field values in a query
- [Django]-Unique BooleanField value in Django?
1
Use this package: https://github.com/ierror/django-js-reverse
You’ll have an object in your JS with all the urls defined in django. It’s the best approach I found so far.
The only thing you need to do is add the generated js in the head of your base template and run a management command to update the generated js everytime you add a url
- [Django]-Django ManyToMany filter()
- [Django]-Redirect to named url pattern directly from urls.py in django?
- [Django]-How to make a PATCH request using DJANGO REST framework
0
One of the solutions I came with is to generate urls on backend and pass them to browser somehow.
It may not be suitable in every case, but I have a table (populated with AJAX) and clicking on a row should take the user to the single entry from this table.
(I am using django-restframework and Datatables).
Each entry from AJAX has the url attached:
class MyObjectSerializer(serializers.ModelSerializer):
url = SerializerMethodField()
# other elements
def get_url(self, obj):
return reverse("get_my_object", args=(obj.id,))
on loading ajax each url is attached as data attribute to row:
var table = $('#my-table').DataTable({
createdRow: function ( row, data, index ) {
$(row).data("url", data["url"])
}
});
and on click we use this data attribute for url:
table.on( 'click', 'tbody tr', function () {
window.location.href = $(this).data("url");
} );
- [Django]-Celery: WorkerLostError: Worker exited prematurely: signal 9 (SIGKILL)
- [Django]-How can I return HTTP status code 204 from a Django view?
- [Django]-How to get POST request values in Django?
0
I always use strings as opposed to integers in configuring urls, i.e.
instead of something like
... r'^something/(?P<first_integer_parameter>\d+)/something_else/(?P<second_integer_parameter>\d+)/' ...
e.g: something/911/something_else/8/
I would replace ‘d’ for integers with ‘w’ for strings like so …
... r'^something/(?P<first_integer_parameter>\w+)/something_else/(?P<second_integer_parameter>\w+)/' ...
Then, in javascript I can put strings as placeholders and the django template engine will not complain either:
...
var url = `{% url 'myapiname:urlname' 'xxz' 'xxy' %}?first_kwarg=${first_kwarg_value}&second_kwarg=${second_kwarg_value}`.replace('xxz',first_integer_paramater_value).replace('xxy', second_integer_parameter_value);
var x = new L.GeoJSON.AJAX(url, {
style: function(feature){
...
and the url will remain the same, i.e something/911/something_else/8/
.
This way you avoid the integer parameters replacement issue as string placeholders (a,b,c,d,…z) are not expected in as parameters
- [Django]-Django, Models & Forms: replace "This field is required" message
- [Django]-Django Many-to-Many (m2m) Relation to same model
- [Django]-Uwsgi installation error in windows 7