Django: how to get a javascript value from template to view? - django

I am currently using Django framework.
I would like to get the value of a javascript value wrote in an html file.
I would like to be able to display it in my view file
Here is my html file from the folder templates:
<script>
var toto = "javascript";
document.write(toto)
</script>
This is my view file:
def javascript(request):
# print the javascript value here
return render(request, "rh/javascript.html")
Thank you for your help !

You have to consider that your script runs on the client-site whereas the view function runs on the server-side. This is one main challenge when it comes to shifting variables from one end to the other.
To make a long story short:
You will have to make a http request from the client-site (for example using jQuery AJAX) to call the view. Then you can pass the variable via AJAX to the view function and use it for further logic.
Example:
your.html
<script type="text/javascript">
// A CSRF token is required when making post requests in Django
// To be used for making AJAX requests in script.js
window.CSRF_TOKEN = "{{ csrf_token }}";
</script>
<div id="variable">Variable</div>
javascript
(function($) {
// trigger the logic on click of the container
$('#variable').on('click', function() {
// assign variable
var variable_for_view = $(this).html();
// make http request using AJAX
$.ajax({
type: 'post',
url: '/your_url/', // this is the mapping between the url and view
data: {
'variable': variable, // ! here is the magic, your variable gets transmitted to the server
'csrfmiddlewaretoken': window.CSRF_TOKEN
},
success: function(data) {
print(sliced_variable)
},
});
});
}(jQuery));
views.py
def your_view(request):
# Assign variable from AJAX request
variable = request.POST.get('variable')
print(variable)
variable.slice(3)
context = {
'sliced_variable': variable
}
return render(request, 'your.html', context)

Related

Django Ajax Dropdown Select2 not return data

There is a dropdown form that I created with ajax. The form works without using the Select2 tag and returns data. But when I enter the select2 tag, it does not show the detail that should be displayed according to the selection.
I use select2 for all select fields in the system. That's why I defined the select2 tag on my layout template like this.
<script>
$('.select').select2({
allowClear: true
});
</script>
Here is my ajax code :
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$("#id_worksite_id").change(function () {
const url = $("#subunitForm").attr("data-subunit-url");
const worksiteId = $(this).val();
$.ajax({
url: url,
data: {
'worksite_id': worksiteId
},
success: function (data) {
$("#id_upper_subunit_id").html(data);
}
});
});
Thank you for your help, best regards

Django & Ajax : data get lost between the view and the template

Using Ajax and Django, my data get lost when sent back to my template and I can't retrieve them.
Here is my code and the logic :
Following the dependent dropdown lists tutorial offered by ["Simple is Better Than Complex"][1]
I have implemented an Ajax request.
Here is the html code:
<p class="multiple-choice" id="mandate-city" data-url="{% url 'officials:ajax_load_mandate_city' %}">Local Mandate: {{ form.mandate_city }}</p>
The ajax request is fired from this script:
<script>
$("#id_departments").change(function (){
var url = $("#mandate-city").attr("data-url");
var departmentId = $(this).val();
$.ajax({
url: url,
data: {
'department': departmentId
},
success: function (data){
$("#id_mandate_city").html(data);
console.log(data);
}
});
});
</script>
After check with console.log, the data are collected by the script. Then, they reach the view.
Here is my view:
def load_mandate_city(request):
department_id = request.GET.get('department')
mandate_city = MandateCity.objects.filter(department_id=department_id).order_by("department")
return render(request, "officials/mandate_city_list.html", {mandate_city: mandate_city})
With a print, I have checked, and the data are treated as planned.
Then the data are sent back through the url:
path('ajax/load_mandate_city/', views.load_mandate_city, name="ajax_load_mandate_city")
They seem not to reach the template:
{% for mandate in mandate_city %}
<option value="{{ mandate.pk}}">{{ mandate.get_mandate_display }}</option>
{% endfor %}
And I could not track them in my script. :-/
Can somebody let me know where the bug is ?
Thanks.
[1]: https://simpleisbetterthancomplex.com/tutorial/2018/01/29/how-to-implement-dependent-or-chained-dropdown-list-with-django.html
did you try to return the information in a json object and then render it with client side js? in general when you use ajax (or fetch) you wanna use the information returned so it's better to return it as a data type,
if you do want to return the html response you should probably not use ajax but rather a form

Ajax with primary key in url of Django cannot work

all, i am using Django to do a social website and now i am trying to do friend network.
The problem i encountered now is when i am using ajax to pass user id in url and it throw url cannot be found error, maybe see code the will be much clearer.
the code is as following
i tried to take awayid, that is , take away all id in ajax, url, and method, then it can work. but if i add id parameter in, then it cannot work
html template
<button class="add-friend-btn" id="add-friend"> Add friend
<script src="{% static 'account/js/friends.js'%}" type="text/javascript" ></script>
<script type="text/javascript">
var userprofilePk = "{{userprofile.pk}}"; // other user's id(primary key)
</script>
{% endif %}
javascript friend.js
$(document).ready(function() {
var addFriend = document.getElementById('add-friend');
addFriend.addEventListener("click", function (event) {
$.ajax({
type: 'POST',
headers: { "X-CSRFToken": csrftoken },
url: "ajax/friend-request/send/"+userprofilePk+"/",
data: {
"test": "test",
},
dataType: 'json',
success: function (data) {
},
error: function (error) {
},
});
});
});
Django url
urlpatterns = [
re_path("ajax/friend-request/send/<pk>/", views.send_friend_request, name="user_send_request"),
]
views.py
def send_friend_request(request, id):
print("send_friend_request")
payload = {"test": "test"}
return HttpResponse(json.dumps(payload), content_type='application/json')
the error message is:
Not Found: /account/profile/sm10547/ajax/friend-request/send/2/
app_1 | HTTP POST /account/profile/sm10547/ajax/friend-request/send/2/ 404 [0.01, 172.18.0.1:38852]
If you are using normal URL dispatcher like path use path
converters to capture URL parameters like <int:pk> for example:
path("ajax/friend-request/send/<int:pk>/",
views.send_friend_request, name="user_send_request"). docs for path()
If you're using regex URL dispatcher like re_path use regular
expression to catch URL parameters like (?P<pk>[0-9]) for example: use re_path(r"ajax/friend-request/send/(?P<pk>[0-9])/$", views.send_friend_request, name="user_send_request"). docs for re_path()
In your case use re_path(r"ajax/friend-request/send/(?P<pk>[0-9])/$", views.send_friend_request, name="user_send_request") it should work fine.

How to redirect whole page when remote posts to iframe in Django

I am working on using Paypal payments advanced embedded / hosted checkout pages in my django site. I display an iframe for the paypal payment page, I submit the request, and it posts back to my site.
The view that handles the paypal response uses
response = redirect("shop_complete")
return response
but this makes my whole response page pop up in the iframe. I could just use a template that would look all right in that spot, but I would like to update the cart and the payment step at the same time. Is there anyway to make that response redirect the whole browser instead of just the frame?
So, my solution wound up being to add an intermediary page that consist entirely of a script to redirect the top level of the browser. I got this script from
JavaScript post request like a form submit
<body>
<script type="text/javascript">
function post_to_url(path, params, method) {
method = method || "post"; // Set method to post by default if not specified.
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
form.setAttribute("target", "_top" )
for(var key in params) {
if(params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
};
window.onload = post_to_url('{% url "shop_paypal_redirect" %}',
{csrfmiddlewaretoken: '{{ csrf_token }}',
result: '{{ result }}'});
</script>
</body>

Backbone Collection

I was trying to make a Backbone Application with Django at its backend. I was following a Backbone tutorial. I used the following code:
Code
<!doctype html>
<html lang = "en">
<meta charset = "utf-8">
<title>IstreetApp</title>
<link rel="stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Book Manager</h1>
<hr />
<div class="page"></div>
</div>
<script type = "text/template" id = "booklist.template">
</script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.10/backbone-min.js"></script>
<script>
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.url = 'http://backbonejs-beginner.herokuapp.com' + options.url;
});
var Books = Backbone.Collection.extend({
url: '/books'
});
var BookList = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var books = new Books();
books.fetch({
success: function(books) {
var template = _.template($('#booklist.template').html(), {books: books.models});
that.$el.html(template);
}
})
}
});
var Router = Backbone.Router.extend({
routes: {
'': 'home'
}
})
var bookList = new BookList();
var router = new Router();
router.on('route:home', function () {
bookList.render();
});
Backbone.history.start();
</script>
</body>
</html>
Since the collection is not defined, the success code doesn't execute. I suppose the collection data should come from the server through Django but I am not sure how and in what form. Kindly help. I am pretty much new to backbone and Django.
When you call fetch on your collection, it makes an AJAX request to:
http://backbonejs-beginner.herokuapp.com/books
However, there is no API set up there. Either one of two things needs to happen:
1) you need to modify your code to point to a different URL, one that does have an existing API (perhaps whatever tutorial you are using has such an API)
2) you need to create such an API yourself on yoursever.com (and then make your Backbone code point to that API's URL instead)
Without a server to support it, operations like save and fetch and such in Backbone simply cannot function.
As a side note, Django is a web site framework. While you can use it to create server-side APIs, that's not really Django's focus. Because of this, several good third party libraries exist for doing RESTful APIs (ie. the kind that Backbone likes) in Django; personally I'd recommend either Django REST Framework (I use it and it works great) or TastyPie (never used it, but it's very popular).
When using a backbone collection you need to return a json array of objects from your api url (http://backbonejs-beginner.herokuapp.com/books)
Example
{[{"name":"bookname", "publisher": "penguin"}, {"name":"bookname", "publisher":"penguin"}]}
You'll also want a model for your collection. A model would look like this
Example:
var Book = Backbone.Model.extend({
defaults: {
"name": "",
"publisher": ""
}
});
The way that the collection works is by parsing the json array and turning each object in the array in to a model that you specific (in this instant an individual book with values for the name and publisher).
When you make a .fetch() on your model you are making a GET request, so make sure that your http://backbonejs-beginner.herokuapp.com/books url is prepared to receive GET requests and respond with the json data in the format I specified up top.