Passing Python Data to JavaScript via Django
n.b. see 2018 update at the bottom
I recommend against putting much JavaScript in your Django templates - it tends to be hard to write and debug, particularly as your project expands. Instead, try writing all of your JavaScript in a separate script file which your template loads and simply including just a JSON data object in the template. This allows you to do things like run your entire JavaScript app through something like JSLint, minify it, etc. and you can test it with a static HTML file without any dependencies on your Django app. Using a library like simplejson also saves you the time spent writing tedious serialization code.
If you aren't assuming that you're building an AJAX app this might simply be done like this:
In the view:
from django.utils import simplejson
def view(request, …):
js_data = simplejson.dumps(my_dict)
…
render_template_to_response("my_template.html", {"my_data": js_data, …})
In the template:
<script type="text/javascript">
data_from_django = {{ my_data }};
widget.init(data_from_django);
</script>
Note that the type of data matters: if my_data
is a simple number or a string from a controlled source which doesn't contain HTML, such as a formatted date, no special handling is required. If it's possible to have untrusted data provided by a user you will need to sanitize it using something like the escape or escapejs filters and ensure that your JavaScript handles the data safely to avoid cross-site scripting attacks.
As far as dates go, you might also want to think about how you pass dates around. I've almost always found it easiest to pass them as Unix timestamps:
In Django:
time_t = time.mktime(my_date.timetuple())
In JavaScript, assuming you've done something like time_t = {{ time_t }}
with the results of the snippet above:
my_date = new Date();
my_date.setTime(time_t*1000);
Finally, pay attention to UTC - you'll want to have the Python and Django date functions exchange data in UTC to avoid embarrassing shifts from the user's local time.
EDIT : Note that the setTime in javascript is in millisecond whereas the output of time.mktime is seconds. That's why we need to multiply by 1000
2018 Update: I still like JSON for complex values but in the intervening decade the HTML5 data API has attained near universal browser support and it's very convenient for passing simple (non-list/dict) values around, especially if you might want to have CSS rules apply based on those values and you don't care about unsupported versions of Internet Explorer.
<div id="my-widget" data-view-mode="tabular">…</div>
let myWidget = document.getElementById("my-widget");
console.log(myWidget.dataset.viewMode); // Prints tabular
somethingElse.addEventListener('click', evt => {
myWidget.dataset.viewMode = "list";
});
This is a neat way to expose data to CSS if you want to set the initial view state in your Django template and have it automatically update when JavaScript updates the data-
attribute. I use this for things like hiding a progress widget until the user selects something to process or to conditionally show/hide errors based on fetch outcomes or even something like displaying an active record count using CSS like #some-element::after { content: attr(data-active-transfers); }
.
Django Template Variables and Javascript
The {{variable}}
is substituted directly into the HTML. Do a view source; it isn't a "variable" or anything like it. It's just rendered text.
Having said that, you can put this kind of substitution into your JavaScript.
<script type="text/javascript">
var a = "{{someDjangoVariable}}";
</script>
This gives you "dynamic" javascript.
How to send data from javascript function to Django View
You can use ajax
to send data to Django view like following code.
javascript:
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
$.ajax({
type: "GET",
url: '/my_def_in_view',
data: {
"result": result,
},
dataType: "json",
success: function (data) {
// any process in data
alert("successfull")
},
failure: function () {
alert("failure");
}
});
}
urls.py:
urlpatterns = [
url(r'^my_def_in_view$', views.my_def_in_view, name='my_def_in_view'),
...
]
views.py:
def my_def_in_view(request):
result = request.GET.get('result', None)
# Any process that you want
data = {
# Data that you want to send to javascript function
}
return JsonResponse(data)
If it was successfull it goes back to "success" part.
Related Topics
Lodash Remove Duplicates from Array
Why Do Arrow Functions Not Have the Arguments Array
JavaScript Custom Event Listener
Detect When a Window Is Resized Using JavaScript
How to Access Dom Elements in Electron
How to Create a Custom Error in JavaScript
How to Store a Global Value (Not Necessarily a Global Variable) in Jquery
How to Listen for a Click-And-Hold in Jquery
Reason Behind This Self Invoking Anonymous Function Variant
Ajax Call and Clean JSON But Syntax Error: Missing ; Before Statement
How Is a Promise/Defer Library Implemented
How to Register Event with Useeffect Hooks
How to Check If Element Has Any Children in JavaScript
Event Listener for When Element Becomes Visible
Differencebetween Using Constructor VS State = {} to Declare State in React Component
Paste an Image from Clipboard Using JavaScript