Create a Fullstack app with Django, GraphQL and VueJS (Part 2)

Babajide Ogunjobi
Nov 1 · 9 min read

In the first part of this tutorial, we created a fictional employee management system using Django and Graphene which allowed us to see all employees, create new entries as well as updating and deleting existing entries.

In this second part, we will continue from where we left off and build a simple VueJS application which we can use to view our employees and filter by cities.

Prerequisites

In order to start working with vueJS and other front end tools, one of the first things we need is a runtime. The most popular javascript runtime is NodeJS which we need for this project.

So head on to the NodeJS website and download the version for your machine. Once the installation is completed, open your terminal and confirm that it exists. Type node -v and you should get a response with a version number

$ node -v
v11.10.0

NodeJS comes packaged with npm which is a javascript package manager which essentially makes it easy for developers to download and install needed packages (similar to pip in python). You can also confirm that it is installed by typing the command below

$ npm -v
6.7.0

Lastly, we want to install vueJS and vue-cli. This is where the advantage of npm comes in

sudo npm install -g @vue/cli

Adding sudo to your vueJS install statement is not mandatory but you may get an error in some cases, especially if you are not logged in as an admin on your computer. Once that download is complete, you can confirm the installation by just typing “Vue” in your terminal

$ vue
Usage: vue <command> [options]
Options:
-V, — version output the version number
-h, — help output usage information
Commands:
create [options] <app-name> create a new project powered by vue-cli-service
add [options] <plugin> [pluginOptions] install a plugin and invoke its generator in an already created project
invoke [options] <plugin> [pluginOptions] invoke the generator of a plugin in an already created project
inspect [options] [paths…] inspect the webpack config in a project with vue-cli-service
serve [options] [entry] serve a .js or .vue file in development mode with zero config
build [options] [entry] build a .js or .vue file in production mode with zero config
ui [options] start and open the vue-cli ui
init [options] <template> <app-name> generate a project from a remote template (legacy API, requires @vue/cli-init)
config [options] [value] inspect and modify the config
upgrade [semverLevel] upgrade vue cli service / plugins (default semverLevel: minor)
info print debugging information about your environment
Run vue <command> — help for detailed usage of given command.

Now we’re ready to begin

1). Navigate to a location on your local drive where you want to create your project and create a folder for your application. In my case, I’m going to my desktop and creating a directory called “vueapps” and changing into the directory

$ cd ~/Desktop
$ mkdir vueapps && cd vueapps

I will now create a new vueJS app called “company”

$ sudo vue init webpack company

You will go through a number of prompts similar to the image below. Select your preferences as required.

After the installation is completed, you should now see a directory with the same name as your project. When you change into the directory, you should see the following files and directories

$ cd company

2). The next step will be to install all of the plugins that were bundled with vueJS and vue-cli. If you open the “package.json” file, you will see a list of all the plugins and dependencies

To install all of these dependencies, run “npm install”. Make sure that you are inside the company app directory

$ sudo npm install

Just a side note that all of the plugins will be installed within the node_modules subdirectory. If everything runs fine, you should see a message similar to below (may be more or less packages depending on your system)

audited 11689 packages in 5.466s
found 0 vulnerabilities

Now we can create a development server to start working on our application within the local computer

$ npm run devI Your application is running here: http://localhost:8080

You can now navigate to the localhost IP provided and you should see a screen similar to the image below

Now, we are ready to start building our application

3). If you are familiar with Vue, you will know that Vue is akin to a single page application (SPA) which is made up of multiple components and routes.

Majority of our code will exist in the “src” directory where all of the components for our application will reside in the “components” subdirectory.

The demo page (http://localhost:8080) that we navigated to after our installation is a product of the HelloWorld.vue file (component). Each component is made up of a template tag, a script tag and a style tag.

However, the App.vue file is parent SPA file for the application where all components and routers need to be registered in order for them to be displayed within the browser. Even though all of the data that is displayed in the browser is created and exists in the HelloWorld.vue file, it needs to be registered in the App.Vue file or else it will not be displayed

Now we will need to create a new component to visualize our company data. Make sure that you are within the src/components directory and create a new component

$ cd src/components
$ sudo touch Comp.vue

4). Open up the new Comp.vue file and start with a simple component where the root div in the template simply prints out “Hello World”, an empty function and no style.

We also need to add a selector (CompanyData) within the script tag and register it in the App.vue file in order for the component to work.

5). Now, we have to go to the App.Vue file to register this new component. Notice the new line additions (lines 5, 11 & 17)

Let’s view our changes by running the dev server again and navigate to the browser

$ npm run dev

You should now see your “Hello World” component at the bottom of the page. Success!

Now we can start working to organize and visualize the data from our django application.

6). For our company application, we want to be able to list all of the current employees within the company as well as having the ability to filter by city. In order to make this visually appealing and easily readable, we’ll use a bootstrap table to display all the pertinent data.

First of all, we will install bootstrap

$ npm install bootstrap

7). I won’t dive too much into the styling aspects since this is not a webpage design tutorial and I assume that if you are reading this, you have a pretty good grasp of CSS.

For my page:

  • I imported the bootstrap stylesheet from the node_modules directory into the style block at the bottom of the App.vue file (line 57)
  • Commented out the App.vue default styles (lines 59–64)
  • Added a navbar which I copied from the bootstrap site (lines 3–37)
  • Commented out the default HelloWorld component (line 38)

You can now see that all that is left on the page is the new navbar and the our “Hello World” comment

Hope your page looks similar to mine.

We finally get to the fun stuff! We get to connect our Vue application to the GraphQL API.

8). We will need to install axios in order to make HTTP requests from our application.

npm install axios

In order to continue, you have to make sure that your django application from part 1 of this tutorial is running. If not, navigate to the directory and run python manage.py runserver. Navigate to http://127.0.0.1:8000/graphql to confirm that Django app is running

9). Let’s make some edits to the Comp.vue file to be able to GET data from the API.

  • Import axios into the Comp.vue file within the script tag (line 13)
  • Add an async mounted lifecycle hook (line 21)
  • Add a data function to collect data (lines 16-20)
  • Create a POST method to query the GraphQL API (line 24)
  • Use a simple GraphQL query to return data (AllTitles) (lines 27–39)
  • Add a directory container within the template tag to return results/data to the page (line 18)

Save and refresh your Vue app now.

10). Let’s see if we can see the returned data in the browser console now. Open “inspect element” on your browser and go to the console tab.

If you see an error mentioning that your request has been blocked by a CORS policy, don’t be alarmed. I actually did that on purpose.

If you’ve worked on any application which requires you to make HTTP requests, you’ve most likely hit a CORS error at least once in your lifetime. This is usually the case when a web application makes a request from a resource that has a different origin (domain, protocol, port) from its own. In our case, even though both applications are running on localhost, they are running on two different ports.

11). In order to solve this, we have to make some slight changes to our django application. First of all, we need to install django-cors-headers

pipenv install django-cors-headers

Add “corsheaders” to the list of installed apps in the settings.py file

INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘graphene_django’,
‘company’,
‘corsheaders’, #added for cors
]

Add “corsheaders.middleware.CorsMiddleware” to the middleware list in the settings.py file

MIDDLEWARE = [
‘corsheaders.middleware.CorsMiddleware’, #added for cors
‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,
]

Lastly, add a whitelist of all inbound urls that will be making requests to the GraphQL server to the bottom of the settings.py file

CORS_ORIGIN_WHITELIST = (
‘localhost:8080/’
)

Now, let’s restart your Django app && restart your Vue app and try again.

The error should now be gone and now we can see data returned (even though it does not look pretty).

12). In order to make the data look more presentable, I’m going to add a bootstrap table to display the data. I’m also going to use this opportunity to change the GraphQL query to return all employees in the company (AllEmployees)

  • I changed the query from AllTitles to AllEmployees (lines 40–55)
  • Added a bootstrap table and created a for-loop within the table tag to return the data in rows (lines 4–19)

Now this looks a lot better and more presentable!!

While this looks great. This is only returning data and is not making great usage of our GraphQL server.

13). Let’s add a search function to our app to allow users to be able to search for employees using the city.

  • I added a search form (lines 4–9) with a “city” v-model
  • Added a city variable to the data function to hold the value entered into the form (line 36)
  • Wrapped the async mounted function with a method (line 40)
  • Added a query filter and the city variable to the GraphQL query (line 49)

You should now be able to see a search box at the top of the page but you will also notice that the table is not returning any data anymore. This is because it now requires you enter a city name for it to return results.

I’ll enter “New York” in the search box and hit ENTER

Same for “Miami”

Looking great now!!

You should now be able to add more data to the django server and retrieve it from the VueJS frontend.

Thank you for taking the time to read through the two parts of this tutorial and apologies for the long wait in completing the series. If you want to see the repo for this project, you can click here

Good luck!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade