How can I use the variables from views.py in JavasScript, script/script in a Django template?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In a Django application you frequently need to send data from the server (Python) to the browser (JavaScript). Because Django templates render on the server before the HTML reaches the client, you must serialize your Python variables into a format that JavaScript can read. This article covers four reliable techniques, from the simplest template tag approach to a full REST API, so you can choose the one that fits your project.
Passing Data Through Template Context
The most direct method is to render a Python variable straight into a \<script> block. In your view you add the variable to the context dictionary, and in the template you use Django's {{ }} tag to inject it.
This works for simple scalar values, but it breaks when the data contains quotes, angle brackets, or other characters that interfere with HTML or JavaScript parsing. For anything beyond plain numbers or pre-sanitized short strings, you should use one of the safer approaches below.
Using the json_script Filter
Django 2.1 introduced the json_script template filter specifically for passing data to JavaScript safely. It serializes the value to JSON inside a \<script type="application/json"> tag, automatically escaping characters like \<, >, and & that could lead to cross-site scripting (XSS).
The filter writes the JSON into a hidden script element with the given id. Your JavaScript then reads and parses it. Because the serialization and escaping happen on the server, this approach is both XSS-safe and easy to use.
Using HTML Data Attributes
If you only need to pass a small number of values and prefer to keep your JavaScript in external files (where Django template tags are not available), you can attach data to an HTML element with data-* attributes.
Be careful with mark_safe: it tells Django to skip auto-escaping, so you must ensure the data is safe before marking it. For untrusted user input, prefer json_script instead.
Fetching Data from a DRF API Endpoint
For complex or frequently updated data, the cleanest architecture is to serve it through a dedicated API endpoint using Django REST Framework (DRF). The template loads with no embedded data, and JavaScript fetches what it needs asynchronously.
This approach separates concerns cleanly: Django serves HTML, DRF serves data, and JavaScript handles rendering. It also makes it trivial to reuse the same endpoint for mobile apps or third-party integrations.
Common Pitfalls
- XSS through unescaped context variables: Injecting
{{ variable }}directly into a\<script>block without thejson_scriptfilter can allow script injection if the variable contains user-supplied content. - Forgetting the CSRF token on fetch requests: Django rejects POST, PUT, and DELETE requests that lack a valid CSRF token. Always include the
X-CSRFTokenheader when calling your own API from JavaScript. - Using
safeormark_safeon untrusted data: These functions disable Django's auto-escaping. Apply them only to data you have sanitized yourself, such as the output ofjson.dumps()on server-controlled values. - Embedding large datasets in the template: Serializing thousands of rows into the HTML increases page weight and time-to-first-byte. For large payloads, use an API endpoint with pagination instead.
- Assuming template tags work in external
.jsfiles: Django only processes template tags inside template files. If your JavaScript lives in a static file, usedata-*attributes,json_script, or an API call to pass the data.
Summary
- For simple, trusted scalar values, render them directly into a
\<script>block via Django template context variables. - For structured or user-supplied data, use Django's built-in
json_scriptfilter, which handles JSON serialization and XSS escaping automatically. - For external JavaScript files, attach data to HTML elements with
data-*attributes and read them withelement.dataset. - For complex or frequently changing data, create a DRF API endpoint and fetch the data asynchronously with JavaScript.
- Always consider security: avoid
mark_safeon untrusted input, include CSRF tokens on mutating requests, and preferjson_scriptover raw variable injection.

