How to Integrate Django and Vue JS Part -1

||
Posted 3 years, 9 months ago
||
Views 1472
||
8 min read
1 reaction

Welcome Techions. In this section we are going to explore how to integrate the Vue JS framework into Django Projects.

 

In this tutorial, I am going to explain the basic integration, but obviously you can extend as much you can. Also make it simple, I am going to stick with Django not with Rest Framework. But in your regular project, its highly recommended to use the Rest Framework library that make our life easier.

Prerequiste,

Ok , Let's move on. First thing first, we need to create the Django Project

django-admin.exe startproject tutorial

Lets create the separate app as well,

(env) PS C:\blogs\tutorial> python .\manage.py startapp vuejs

Just for Demo purpose, I am going to create the simple model where we can hold the various blogs from our Teckiy Site

So, we need to create the model in vue.js/model.py file

from django.db import models

# Create your models here.


class BlogLink(models.Model):
    title = models.CharField(max_length=200)
    link = models.URLField()

    def __str__(self):
        return self.title

Now, we can create our view to render the data,

from django.shortcuts import render
from django.http import JsonResponse
from .models import BlogLink

# Create your views here.


def blog_view(request):
    object_list = BlogLink.objects.all()
    return render(request, 'vuejs/blog_list.html', {'object_list': object_list})

In order to render this, we need to create the URL pattern in our projects/urls.py file just like below,

from django.contrib import admin
from django.urls import path
from vuejs.views import blog_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blog_view)
]

Now , its time to create the template folder(templates/vuejs/blog_list.html and place some basic bootstrap html skeleton,

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
        integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <title>Hello, world!</title>
</head>

<body>
    <h1>Hello, world!</h1>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"
        integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
        crossorigin="anonymous"></script>
</body>

</html>

Now if you navigate to localhost. You should able to see the output like this in your browser,

Ok, Now lets add some data into our model and view in our html page,

#add this line in admin.py file to see the model in admin page,


from django.contrib import admin
from .models import BlogLink

admin.site.register(BlogLink)

Now, I have added the 2 blog links from our Teckiy site , just like below,

We can try render the data in our Html using regular Django Template approach,

    <div class="container mt-5 pd-5">
        {% for list in object_list %}
        <h3> {{ list.title }}</h3>
        {% endfor %}
    </div>

Output should like this,

Ok woow, evrything looks perfect smiley. Then why should i need to implement Vue JS here. Well, as of now using regular Django Template, we need to send the request to backend(Django) everytime when we do some kind of Operations( Of course for CRUD we need to use Django) but how come with refreshing the page. This is where Vue JS will help us to develop the Single Page Application(SPA) to peform the action in backend without refreshing the page,

Now, we are going to start integrating the Vue Js into our Html, we are not going to discuss about Vue Js concept here, rather we just see how to integrate and use it,

In this section we are going to Vue JS CDN method not CLI approach, so just to make sure , we are not going to have any separate module to handle it.

In Vue Js, we need to wrap the entire sets in a given root tag, which means if you want to add the Vue Js in base html then after the body all the relavent HTML should be wrapped with a <DIV> class like this,

Just like below,

<div id="app">
        {% for list in object_list %}
        <h3> {{ list.title }}</h3>
        {% endfor %}
</div>

We will discuss more about template tag with in Vue app later,

Vue JS is Javascript framework , so we need to think about how we can pass the data from our View to Vue Js to render it in front end. As I mentioned in beginning, if we go with Rest Framework approach then it is more easier than regular Django, but we stick with regular Django approach only, but we need to do some adjustment in our View render to return JSON data.

Before that , lets integrate Vue JS script in our html, we need to add the below script in our blog_list.html file,

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

Above script tag should be place, in order to access the Vue instance. So make sure to add the script after our </div> tag .

Ok Now, lets create our first Vue instance to handle progressive page,

After the above script tag, we can create the new script tag and place the new Vue instance and other components related to Vue.

  <script>
        var app = new Vue({

        });
    </script>

This is one of the way to create the new Vue instance, here we can pass the props,data,method,components etc. For more info, check here

Now , lets take a look how can we pass the data from Vue to HTML,

In order to access the Vue instance, if you remember we have wrapped the html container in div tag with id=app right?

We can use that now, to render the data for Vue instance just like below,

        var app = new Vue({
            el: '#app',
            data: {
                message: 'Hello Techion!',
            }
        });

If you see the above script, we have used "el" identifier to grab the div id "app", This is how, we can render the data to HTML using the id, Also if you noticed, I have added the data object in instance, this is the way we need to pass the data from Vue to Html. Now, how can we render the "message" variable in our HTML. Just simple, we can use Vue Template tag {{ message }} like this to render it. Lets see in action,

    <div id="app">
        <div class="container mt-5 pd-5">
            {% for list in object_list %}
            <h3> {{ list.title }}</h3>
            {% endfor %}
            <br />
            {{ message }}
        </div>
    </div>

This is how, we need to render the message in html. If you refresh the http://localhost:8000/ you will not see the "Hello Techion!" message in our page. Wait a minute, I have rendered the variable correctly but why still I am not able to see it. Reason is, Vue template syntax is conflicting with Django Template method {{ }}. So we need to force the Vue JS to use different delimiter to access the variable, so we can use 

delimiters: ['[[', ']]'],
 <script>
        var app = new Vue({
            el: '#app',
            delimiters: ['[[', ']]'],
            data: {
                message: 'Hello Techion!',
            }
        });
    </script>

Now,we need to use [[ ]] template string instead of {{ }}. Using this option we can access both Django template and Vue Template, 

    <div id="app">
        <div class="container mt-5 pd-5">
            {% for list in object_list %}
            <h3> {{ list.title }}</h3>
            {% endfor %}
            <br />
            [[ message ]]
        </div>
    </div>

Now, we can see the "Hello Techion!" message in our page.

Note: Some side effects also need to understand here, We may not able to use the ES6 functionality into this approach. As some of the old browser even in IE11 will not support this.

Thanks to Frank-Stevensmiley. He pointed out the some of the challenge of using Vue.Js integration option in Django Template.

"Look at the following very simple code I included within script tags in a Django template. Works as expected in modern browsers. Crashes the whole JS in Internet Explorer 11 (not even only using the old ES5 syntax function alone would work):
 

<script>
var app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
data: {
message: 'Vue.js initiated!',
sidebar: false,
},
methods: {
greetES5: function() {
console.log("Old ES5 JS test.");
},
greetES6: () => {
console.log("Newer ES6 JS test.");
},
},
created() {
this.greetES5()
this.greetES6()
}
})
</script>"

Above script may not work properly in IE11 but it should work in all other modern browser. Some of the points also needs to be considered,

Integrating vue.js into Django templates like this (which is very charming, I agree) will only work in browsers that support modern ES6 JS features. Yes, that is all recent versions of modern browsers nowadays. Unfortunately, there is still people out there using outdated browsers, like IE11 and some others. For integrating vue.js into Django templates to work like suggested even in the older browsers, we would first need to transpile ES6 JS down to ES5. In a pure / traditional vue.js setup this is done (behind the scenes) by webpack and babel (so there is no problems with IE11 and other older browsers). When it comes to Django, there is no quick and easy way to use modern ES6 JavaScript inside script tags within Djangos templates. Yes, there is one third party tool (django-compressor in combination with django-compressor-toolkit) that could transpile JS used in Django templates down to be ES5 compatible. But it is not recently maintained and currently only usable on Unix based machines. I hope in future releases of Django an easier, more out of the box solution will be provided to simply use modern JavaScript syntax within Django templates.

Ok we just played around with Vue in our HTML file. Now we are going to explore how we can get the data from Django using Vue JS and render it. We will see that in part 2 . Please subscribe here. So that whenever I have posted the part 2 , you will get the notification. For Video lovers, we will defintely post the video in our course section. In case of any doubts you can log a ticket here

Happy Coding !!! 


1 reaction

Discussion

roberto
Posted 6 months, 1 week ago

I couldn't return the message variable. I'm using macOS Mojave and the script won't work. Is there any Github Repo where I can see the entire code? Thanks for any help. Roberto (rthomques@gmail.com)


Dont have repo. Can you please brief more about the error?

- Vengat Posted 5 months, 3 weeks ago


Looking for Freelancing Jobs
Joined on April 15, 2020

Latest Videos