Using VueJS with Django

A translation of the article was prepared ahead of the start of the Python Web Developer course .




Introduction


Now I am working on a very interesting project. And everything is complicated in it, because the project itself is very large-scale, and I deal with it alone in my free time, while working full time. Therefore, I must be effective. Fortunately, I use Django with its “battery included” approach .

I use all the functionality of Django, which speeds up development, and I would not want to lose sight of its template engine. Therefore, the backend for Django and the frontend for JavaScript SPA are not an option for me. However, even the most avid backend developer must admit that some things need to be implemented on the client side. Minor user actions should not require a page reload. In addition, some parts of the web application that I create require a rather complicated user interaction.

By tradition, one could mix Django and jQuery to get the desired behavior. But now there are newer JavaScript technologies like React and Vue. Since our goal is to find a framework that we can use with Django without rewriting everything from scratch, we will use Vue as an easier alternative. In this article, I will show you how to start using Vue with Django with minimal effort.

Installation and setup


One of the reasons to use Vue is its excellent documentation . It has many examples, a decent search and a clear table of contents. The purpose of this article is to show that you can start using Vue in your Django projects right away without the complicated hours-long setup. Therefore, we will use the simplest connection method Vue.js, adding it with via the tag <script>.

<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

Now we are ready to create our first instance Vue.js:

<div id="app">
  {{ message }}
</div>

var app = new Vue({
  delimiters: ["[[", "]]"],
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

I took this example from the official getting started guide. However, there is something else. By default, Django and Vue use the same template tags. Therefore, we need to explicitly separate Vue from Django to avoid conflicts with the Django template engine.

Access Django Data from Vue


The easiest way to get data is to use the built-in filter jscon_scriptfrom Django . This way, you can immediately start using your Django models as data for Vue instances.

In HTML:

{{ django_template_variable|json_script:"djangoData" }}

And then in JavaScript we load the data into a variable:

let jsVariable = JSON.parse(document.getElementById('djangoData').textContent);


And she is ready for use with Vue:

new Vue({
  delimiters: ["[[", "]]"],
  el: '#app',
  data: jsVariable
})

Running asynchronous requests on the backend


One of the most common tasks at the front end on Vue is to query the server application on the backend. With a full Django app, we don’t need to do this with every user action. In some cases, a full page reload is great, and the Django template system will provide all the benefits. But to improve the user experience and take full advantage of Vue, we may still need to make backend requests in some cases.

Vue itself does not know how to handle requests. In this article I will use axiosas it is also recommended by official Vue documentation. You can choose other alternatives. To pass Django's CSRF protection mechanism, axios must include the appropriate cookie in its requests. The easiest way is to set global axios values ​​by default:

axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";

In addition, we can create an axios instance with the necessary settings:

var instance = axios.create({
    xsrfCookieName: 'csrftoken',
    xsrfHeaderName: "X-CSRFTOKEN",
});

Your Django template should contain a tag {% csrf_token %}or, alternatively, the corresponding view should use a decorator ensure_csrf_cookie(). The rest of the default backend for a Django session for authentication will work out of the box, which means that you can annotate your services on the backend with things like loginRequiredthis and it will just work. To make a request, you can use axios:

axios.post('/django/backend/endpoint', {
    data: jsVariable 
})
    .then(function (response) {
        // handle response
    })
    .catch(function (error) {
        // handle error
    });

This call can be made from the mountedhook of the Vue instance or from any other place where you can put JavaScript code.

If you activated CSRF_USE_SESSIONS CSRF_COOKIE_HTTPONLYDjango in the settings, you will need to read the CSRF token from the DOM. To learn more about this, check out the official Django documentation .

Conclusion


When you google about Django + Vue, most of the search results will be about how to use Django on the backend, and Vue for a separate project on the frontend. Having two independent projects complicates the work, and you lose access to the Django template system, which in turn is a very effective way to save time. On the other hand, access to a framework like Vue can do wonders in the world of web applications that go beyond CRUD functionality.

Fortunately, we do not need to choose between them. This guide shows that you can well keep up with two rabbits!



Expanding Django (free webinar).

All Articles