There are many scenarios where you may want to use AJAX requests in your web application. It is a great resource that enables web applications to be faster and more dynamic. For this short tutorial I will be using jQuery to ease the implementation.
You can choose a different framework, or even implement it using JavaScript only. But the concept will remain the same.
Initial Setup
Here is how my base.html template looks like:
The jQuery library and all the JavaScript resources stays in the end of the HTML page for two reasons: to guarantee the DOM will be loaded whe the script is executed and to avoid inline scripts (at least scripts that uses jQuery).
All the extra or page specific JavaScript goes inside the {% block javascript %}{% endblock %}
block.
Sample Scenario
Let’s say you want to validate the username field in a sign up view, as soon as the user finish typing the desired username. You want just to do a simple check, if the username is already taken or not.
views.py
urls.py
signup.html
The view looks like that:
Ajax Request
Let’s implement an asynchronous request to validate if the username is already taken or not.
First we gotta have a look on the HTML generated by the {{ form.as_p }}
. We want to inspect the
username field, which looks like that:
What we need here is its ID, which is id_username. Let’s create a listener for the username’s field change event:
signup.html
This is something I still like to do nowadays, even working with jQuery every single day. Before moving forward, make sure you got the listener right. Make sure the event is firing correctly. In this case, as the name suggests, the change event will occur every time the value of the username field changes.
You can check the output of the console.log()
function in your web browser console. Generally right clicking in the
page and clicking on a menu that says Inspect or something similar.
Let’s create a view that checks if a given username is taken, and return a response as JSON.
views.py
Add a route to this view:
urls.py
And then the simpliest implementation would be:
signup.html
Improving the Example
The example is working, and that’s great. But there are a few details we can improve:
- Hardcoded URL inside the Ajax function
- User message embeded in the JavaScript
Since we are inside a Django template, we could do something like that:
It is already better, but, I don’t really like this strategy. Two reasons: You won’t be able to extract this JavaScript code to a external file. We have an external script modifying our JavaScript. If you find yourself writing code to write a JavaScript code, give it another thought. There might be a better solution.
Now, what I usually like to do:
views.py
Extract the user message to the Python code, this way is easier to work with translations.
signup.html
Ideally I would put the data-validate-username-url
attribute directly in the username field. But here we would
need to expose all the fields in the {{ form.as_p }}
. So in this case I can live with the
attribute in the form tag.
Generally speaking: try to avoid modifying JavaScript code with Python code, keep the URL references in the HTML and manage user messages in the Python code.
Another tip: if you have direct access to the HTML field, prefer adding a class name like this:
And then you hook the change event to the class js-validate-username
instead. The js-
prefix suggests that there is
a JavaScript code that interacts with this element. And then use this prefix for JavaScript only, never use it for
styling the component as well via css.