Connecting Django and Vue

See Django: Tips and Tricks for similar articles.

In this article, we will walk through creating a Django project and integrating Vue.

Why Django?

Django is a powerful Python web framework that can be used to easily build clean, scalable, and secure web apps. Django’s tagline “The web framework for perfectionists with deadlines” gets at its goal to help developers build great web apps quickly. This makes Django a great choice, especially for Python developers, for building any size web application.

According to the Python Developer’s 2021 Survey, Django is the second most popular Python framework just behind Flask. Django is also the ninth most commonly used web framework overall and the most commonly used open-source server-side web framework (just ahead of Flask).

While Django is an incredibly powerful framework for building out your web app, it is used for server-side/backend programming, meaning that any dynamic changes won’t be shown on the browser until the user refreshes the page. This issue can be resolved by partnering with a client-side web framework like React or Vue.

Why Vue?

Vue is a fast and reliable JavaScript framework for building dynamic web user interfaces.

Combining Vue with Django allows you to take advantage of the scalability and security of Django on the backend while still getting speed and reliability on the frontend.

Now, that we know why we are using Django and Vue, let’s get started:

Creating the Django Project

Visual Studio Code is my editor of choice, so I’ll open the folder where I want to create my new project. I’ve named it django-vue.

Now, I will create a Python virtual environment and install Django:

  1. Open the Integrated Terminal in Visual Studio Code.
  2. Run python -m venv .venv to create the virtual environment.
  3. Run source .venv/bin/activate (Mac) or .\venv\Scripts\activate (Windows) to start the virtual environment.
  4. Run pip install django to install Django.
Setting up the virtual environment and installing Django

 

Now, I can create my Django project by running:

django-admin startproject project_name .

I’ll name my project djangovue_project. Starting the Django Vue project

The dot (.) at the end of django-admin startproject project_name . indicates that the project should be created in the current directory. If you leave it off, a new project directory will be created with a nested folder that has the same name, which can be confusing.

My folder structure now looks like this: Django Vue new project folder structure

At this stage, you can run your Django project with python manage.py runserver: Running the Django server

Navigate to http://127.0.0.1:8000/ to see your project in the browser! Django working in the browser

Creating a Django App

Let’s now create a simple games app, which will allow users to play different games and record scores.

  1. To create a new app, run python manage.py startapp app_name: Start Games App
  2. Now, we need to add our new app to the installed apps in Django: Add Games App

Configuring Views, URLs, and Templates

In order for our app to have actual pages that can be seen in the browser we need to configure Django views, urls, and templates.

Views

Let’s configure a few different views for our games app:

  1. Open games/views.py.
  2. Import TemplateView from django.views.generic and create three new views: Create Game Django Views These views will be for a homepage, a page to play a math game, and a page to play an anagram game.

URLs

Let’s configure our URLs for the games app:

  1. Create a file called urls.py inside of the games folder.
  2. Add the following code to create url paths for each of our views: Create URL patterns for games app
  3. Open djangovue_project/urls.py.
  4. Import include from django.urls and add the games urls to project urls: Add games urls to project urls

Templates

After we configure templates, we will be all set to view our pages in the browser!

  1. Create a folder called templates inside of the django-vue folder at the same level as games.
  2. Open up djangovue_project/settings.py and update TEMPLATES so that Django looks for templates in your new templates folder: Update Templates setting
  3. Add the three files we designated as template names (home.html, math-game.html, and anagram-game.html): Create template files
  4. Now add the following simple HTML to each template where [Page Name] is “Home”, “Math Game”, or “Anagram Game”:
            <!DOCTYPE html>
            <html lang="en">
            <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>[Page Name]</title>
            </head>
            <body>
            <h1>[Page Name]</h1>
            </body>
            </html>
          

To see these pages, run the server and go to:

  1. http://127.0.0.1:8000/
  2. http://127.0.0.1:8000/math-game/
  3. http://127.0.0.1:8000/anagram-game/

Template Improvements

We had to repeat that same skeleton code for each of our templates. Let’s take advantage of Django’s template inheritance and build a base template that can be extended by each of our other pages:

  1. Create a new file in the templates folder called _base.html.
  2. Add the following code: Django Base Template
  3. {% block title %}{% endblock %} and {% block main %}{% endblock %} represent the places where we will add our page-specific content. For example, home.html could now look like: Update Home Template
  4. Do the same for math-game.html and anagram-game.html.

We can make an additional improvement to our _base.html template by adding header navigation so that all of our pages have links to each other:

  1. Open templates/_base.html.
  2. Add a header with navigation using the built-in Django url tag: Add header nav to base template

The built-in Django url tag will get the url path for you by interpreting Django urls. The syntax is:

{% url 'namespace:url-pattern-name' %}

 

Now, all of our pages that extend the base template have navigation! Navigation added!

Adding Vue

There are multiple ways to incorporate Vue into your Django project. In this article, we will be showing how you can add Vue to individual pages that need it.

Setting Up Your Vue App

We will be using the Vue CLI to work with Vue.

  1. If you haven’t already installed the Vue CLI, install it by running npm install -g @vue/cli.
  2. After installing, create your Vue app by running vue create app_name (I called my app “vue-games”): Create Vue App Your folder structure should now look like: Post-Vue Folder Structure
  3. You can run your Vue app by running cd app_name and then npm run serve: Run Vue Server
  4. Go to http://localhost:8080/ to view your app in the browser: Welcome to Vue App

Right now, you can run both our Django project and our Vue app, but they run separately. We need to make it so our Vue app will run within our Django project.

Configuring Vue

By default, Vue outputs its code into the public/index.html file. We are going to change its configuration so that it outputs into a Django template instead. We will then be able to extend this template for any pages that we want to include Vue. Let’s get started:

  1. The first thing we will do is create Vue config file. Inside of vue-games, create a file called vue.config.js.
  2. Put the following code into vue.config.js: Vue Config File Here we have set the publicPath, the outputDir, and the indexPath. This configures where our app will be deployed (http://localhost:8080), where build files should go when we run npm run build (static/dist), and where our generated index file should go (templates/_base_vue.html). We also configure the dev server to output our index.html into its file (writeToDisk) rather than preserve it in memory. This allows our Django to access it.
  3. Create a static folder at the same level as games and then create a dist folder inside of it. When you build the app with npm run build for deployment, this is where the app files will go.
  4. Open djangovue_project/settings.py and right below STATIC_URL = 'static/' add the following:
    STATICFILES_DIRS = [
          BASE_DIR / 'static',
      ]
    This lets Django know where to find your static folder.
  5. We need to make some updates to our templates/_base.html so that our _base_vue.html can properly extend it: Update Base Template
  6. Now open vue-games/public/index.html. We are going to convert this into a Django template because Vue draws from this file to create the index file used to render Vue apps: Update Public Index Notice {{ block.super }}, which indicates that the content from the extended template block should be used there.
  7. Change math-game.html and anagram-game.html to extend _base_vue.html instead of _base.html. Update Anagram Template to Extend Vue Base

At this point, you can run both servers (in two separate terminals) and you should see that Vue is included on both game pages: Run Django ServerRun Vue ServerMath Game Running in ServerAnagram Game Running Django

However, notice that both the Math Game and the Anagram Game pages show the same Vue page. We want different Vue pages for each game. To set this up we are going to use Vue Router:

  1. You can stop both servers if you still have them running.
  2. Inside of vue-games/src create a new folder called apps.
  3. Inside of apps create two new Vue files: MathGame.vue and AnagramGame.vue: New Vue Apps
  4. In each of these files, you can add a very simple template. Something like: Math Game Vue template
  5. Now, open the terminal at the vue-games folder and run npm install vue-router@4 to install Vue Router in your Vue project. Instal Vue Router
  6. Inside of vue-games/src create a new file called router.js.
  7. Open router.js and write the following code to set up routes to your two apps: Set up Vue Router routers
  8. Now open vue-games/src/main.js. We need to import our router so that Vue knows to use it: Use Router
  9. Lastly, we need to update the contents of App.vue so that it knows to use our router as well: Make App use router

Now if you run the servers, you will be able to see our page-specific Vue for http://127.0.0.1:8000/anagram-game/ and http://127.0.0.1:8000/math-game/: Anagram Game VueMath Game Vue

Congratulations!

Congratulations! You have integrated Vue with Django!

Written by Jared Dunn.


Related Articles

  1. Connecting Django and Vue (this article)
  2. Creating RSS Feeds with Django
  3. How to Run the Shell for a Django Project within AWS Elastic Beanstalk AMI