DEV Community

Stephen Amedi Imbira
Stephen Amedi Imbira

Posted on

Build a Blog Application: Step-by-step Integration with Django and Vue 3

In the realm of Django development, models, views, URLs, and templates form the cornerstone of every project. These elements converge to sculpt a full-stack Python based web framework, meticulously adhering to the MTV design pattern. However, this project does not employ Django templates for the presentation layer. Instead, it uses Vue 3, a powerful JavaScript framework for building dynamic user interfaces. This innovative solution splits the roles of client and server, revolutionizing the traditional approach to web development.

Setting up Django
Installing Django with pipenv
Setting up Django involves installing it with pipenv, the preferred package management system for creating a virtual environment. To install Django with pipenv, simply run the following command at the shell:

pipenv install django
Enter fullscreen mode Exit fullscreen mode

In addition to installing Django, you’ll also need to install the following packages: djangorestframework and djangocorsheaders. To do so, continue in your terminal or command prompt and execute the following commands.

pipenv install djangorestframework
Enter fullscreen mode Exit fullscreen mode
pipenv install djangocorsheaders
Enter fullscreen mode Exit fullscreen mode

Activate virtual environment

pipenv shell
Enter fullscreen mode Exit fullscreen mode

Creating your first project
Django provides a command that allows you to create an initial project file structure. Run the following command in your shell prompt. Remember to add the dot at the end, so that Django can create the server files in the same folder.

django-admin startproject server .
Enter fullscreen mode Exit fullscreen mode

To initialize the database migrations for your Django project, execute the following command in your terminal or command prompt: it ensures that your database schema aligns with your project’s models and configurations.

python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

To create a new Django app named "blog," navigate to your project directory in the terminal or command prompt and execute the following command:

python manage.py startapp blog
Enter fullscreen mode Exit fullscreen mode

To create the blog data model in your Django project, you can define a model named Article in your models.py Here’s how you can do it:

from django.db import models
from django.contrib.auth.models import User

class Article(models.Model):
      title = models.CharField(max_length=200)
      body = models.TextField()

      def __str__(self):
            return self.title

Enter fullscreen mode Exit fullscreen mode

In this model, we’ve defined an Article class that inherits from Django’s models.Model. It includes two fields: title field which is a character field with a maximum length of 200 characters, and body which is a text field to store the content of the article.

Activating the Application
To activate the newly created "blog" application, along with the third party apps we installed, navigate to your project's settings file (usually located at settings.py) and add blog to the INSTALLED_APPS list. Ensure that it follows the specified format, including third-party apps such as rest_framework and corsheaders. Here's how your INSTALLED_APPS list should look:

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",

    # Third party apps
    'rest_framework',
    'corsheaders',

    # Local apps
    'blog',
]

Enter fullscreen mode Exit fullscreen mode

Creating and Applying Migrations
To create and apply migrations for your Django project, execute the following commands in your terminal or command prompt:

python manage.py makemigrations
Enter fullscreen mode Exit fullscreen mode
python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

Create a superuser
To create a superuser for accessing the Django administration site, execute the following command in your terminal or command prompt:

python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

This command will prompt you to enter a username, email (optional), and password for the superuser account. Once created, you can use these credentials to log in to the Django administration site and manage your blog application.

Django administration site
Now that the Blog model is synchronized with the database, we can establish a straightforward administration site to manage blog posts.
As depicted in the diagram, the Article model is prominently displayed within the admin site.

Image description

Let's proceed by adding two articles using the admin site.

Image description

Building List and Detail Views
These views define endpoints for listing all articles and retrieving a specific article. The article_list view fetches all articles from the database and serializes them. The article_detail view retrieves a single article based on its id.

from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view
from rest_framework.response import Response

from .models import Article
from .serializers import ArticleSerializer

@api_view()
def article_list(request):
      all_posts = Article.objects.all()
      serializer = ArticleSerializer(all_posts, many=True)
      return Response(serializer.data)

@api_view()
def article_detail(request, id):
      post = get_object_or_404(Article, id=id)
      serializer = ArticleSerializer(post)
      return Response(serializer.data)

Enter fullscreen mode Exit fullscreen mode

Making sure the APIs are working
To verify that the APIs are functioning correctly, you can utilize django rest framework’s built-in UI.

Image description

Image description

Setting up the Vue.js
Installing Vue 3
To set up Vue.js for your project, begin by installing Vue 3 using npm. Execute the following command in your terminal or command prompt:

npm create vue@latest
Enter fullscreen mode Exit fullscreen mode

During the installation process, make sure to select 'Yes' when prompted to add Vue Router. This will incorporate Vue Router into your Vue 3 project, enabling client-side routing for seamless navigation within your application.

Image description

cd frontend
npm install
Enter fullscreen mode Exit fullscreen mode

To install Axios, a popular HTTP client for making requests in Vue.js applications, execute the following command in your terminal or command prompt:

npm install axios
Enter fullscreen mode Exit fullscreen mode

In this main.js file, Axios is registered as $axios in the global properties of the Vue app. This allows Axios to be easily accessible from within Vue components using this.$axios. The app is then mounted to the DOM element with the ID app, completing the setup.

import './assets/main.css'
import './assets/main.scss'

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios'

const app = createApp(App)
app.config.globalProperties.$http = axios

app.use(router)

app.mount('#app')

Enter fullscreen mode Exit fullscreen mode

*Fetching data and displaying API data with Vue.js
*

<template>
  <div class="container-fluid">
    <div class="container mt-6">
          <article class="media box has-background-light" v-for="(post, index) in posts" :key="index">

            <div class="media-content">
              <div class="content">
                <p>
                  <p class="title is-4">
                    <RouterLink :to="{ name: 'full', params: { id: post.id } }">{{ post.title }}</RouterLink>

                  </p>
                  {{ truncateWords(post.body, 30) }}
                </p>
              </div>

            </div>
            <div class="media-right">
              <figure class="image is-128x128">
                <img src="../assets/profile.jfif" alt="">
              </figure>
            </div>
          </article>

    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      posts: []
    }
  },

  methods: {
    async getPosts() {
      try {
        const response = await         this.$http.get('http://127.0.0.1:8000/articles/');
        this.posts = response.data;
        console.log(this.posts)

      } catch (error) {
        console.log(error)

      }
    },

    truncateWords(text, limit) {
      const words = text.split(' ');
      if (words.length > limit) {
        return words.slice(0, limit).join(' ') + '...';
      }
      return text;
    }
  },

  created() {
    this.getPosts();
  },
}
</script>

Enter fullscreen mode Exit fullscreen mode

Setting up the Vue Router
In this setup, Vue Router is configured to use the HTML5 history mode for routing. Two routes are defined: one for the home page (/) which corresponds to the ListView component, and another for viewing detailed articles (/articles/:id)which corresponds to the DetailedView component.

import { createRouter, createWebHistory } from 'vue-router'
import ListView from '../views/ListView.vue'
import DetailedView from '../views/DetailedView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: ListView
    },
    {
      path: '/articles/:id',
      name: 'full',
      component: DetailedView
    }
  ]
})

export default router

Enter fullscreen mode Exit fullscreen mode

Detailed

<template>
  <div class="container">
    <h1 class="title">{{ article.title }}</h1>
    <p>{{ article.body }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      article: null
    }
  },

  created() {
    this.fetchArticle();
  },

  methods: {
    async fetchArticle() {
      try {
        const id = this.$route.params.id;
        const response = await this.$http.get(`http://127.0.0.1:8000/articles/${id}/`)
        this.article = response.data;

      } catch (error) {
        console.log(error)

      }
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

The Final Project
Image description

Image description

Top comments (0)