Building a Single-Page Application with Django.

Write a simple single-page django app.

Posted by PythonStacks on October 27, 2020

In this tutorial, I will show you how to implement a very simple single-page application with Django.

We will take advantage of Django's views and JavaScript's fetch API.

 

Setting Up the Project

You should have django installed before starting a django project.

To Install django run the command below in your terminal or workspace.

pip install django

 

To Start a django Project :

django-admin startproject mysite

This will generate a project structure with several directories and python scripts which looks like:

├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py

To know more about the files created,  read: Starting A Django Project

 

After creating a Django project, we need to create a Django app for our single-page app.

Every Django project must contain at least one app.

Navigate into the outer directory where manage.py script exists :

cd mysite

Then run this command:

python manage.py startapp singlepage

These will create an app named singlepage in our project.

Our project directory will look like this:

├── db.sqlite3
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py
└── singlepage
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations/
    ├── models.py
    ├── tests.py
    └── views.py

 

Adding singlepage app to Django settings.

After creating our first django app in the project, we need to inform django that a new application called singlepage has been created.

Open your settings.py file and scroll down to the installed apps

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

 

Now add the new app, singlepage to the installed apps

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'singlepage',                          # down here
]

 

 

Creating  Views

We are going to be using function-based views. A Django view is a function that receives a request and returns a response.

Open your singlepage/views.py and write the code below:

views.py

from django.shortcuts import render
from django.http import HttpResponse, Http404


# Create your views here.
def index(request):
    return render(request, "singlepage/index.html")


texts = ["Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tortor mauris, maximus semper volutpat vitae, varius placerat dui. Nunc consequat dictum est, at vestibulum est hendrerit at. Mauris suscipit neque ultrices nisl interdum accumsan. Sed euismod, ligula eget tristique semper, lecleo mi nec orci. Curabitur hendrerit, est in ",
        "Praesent euismod auctor quam, id congue tellus malesuada vitae. Ut sed lacinia quam. Sed vitae mattis metus, vel gravida ante. Praesent tincidunt nulla non sapien tincidunt, vitae semper diam faucibus. Nulla venenatis tincidunt efficitur. Integer justo nunc, egestas eget dignissim dignissim,  facilisis, dictum nunc ut, tincidunt diam.",
        "Morbi imperdiet nunc ac quam hendrerit faucibus. Morbi viverra justo est, ut bibendum lacus vehicula at. Fusce eget risus arcu. Quisque dictum porttitor nisl, eget condimentum leo mollis sed. Proin justo nisl, lacinia id erat in, suscipit ultrices nisi. Suspendisse placerat nulla at volutpat ultricies"]

def section(request, num):
    if 1 <= num <= 3:
        return HttpResponse(texts[num-1])
    else:
        raise Http404("No such section")

 

The texts variable is a list with 3 dummy texts. They may represent data from the database or a paginated list of blog articles.

The index and section functions are Django views. The index view just renders an HTML file called index.html, we will create that later.

The section view is the view we are going to send a request to in order to get the data from the texts list.

 

Creating the URLs.

After creating our views, we must create URLs that map to each of the views we created. It is through these URLs that we can access our views.

Create a urls.py file in your singlepage application directory and add the following code.

singlepage/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index, name='index'),
    path("sections/<int:num>", views.section, name='section'),
]

The sections/<int:num> means accessing that URL requires an argument of type integer. Example : section/2.

If you don't know much about URLs, you can refer to the Django docs URL dispatcher.

 

Now we need to include these singlepage URLs to the actual project. By opening the mysite/urls.py file, you will see:

mysite/urls.py

from django.contrib import admin

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

 

Modify it to include the URLs from singlepage app:

from django.contrib import admin
from django.urls import path, include                   # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("singlepage.urls")),               # new
]

Requests will now be directed to the singlepage app.

 

Creating Templates

Django allows us to handle HTML code separately from our views and other python code. We are going to keep HTML files in a template directory.

First, open the singlepage directory and create a folder or directory called templates. Secondly, in the templates directory, you create another directory called singlepage.

Finally, in the singlepage directory you just created, create an HTML file called index.html .

├── db.sqlite3
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py
└── singlepage
├── __init__.py
├── admin.py
├── apps.py
├── migrations 
├── templates                     # new directory
    ├── singlepage                # new directory
        ├── index.html            # new HTML file
├── models.py
├── tests.py
└── views.py

 

Now open your index.html and write the following code.

singlepage/templates/singlepage/index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Single Page</title>
        <script>

            //  This function communicates with django (backend)
            
            function showSection(section) {   
                fetch(`/sections/${section}`)
                .then(response => response.text())
                .then(text => {
                    console.log(text);
                    document.querySelector('#content').innerHTML = text;
                });

            }


            document.addEventListener("DOMContentLoaded", function() {
                document.querySelectorAll('button').forEach(button => {
                    button.onclick = function() {
                        showSection(this.dataset.section)
                    }
                })
            });


        </script>
    </head>
    <body>
        <h1>Hello</h1>
        <button data-section="1">Section 1</button>
        <button data-section="2">Section 2</button>
        <button data-section="3">Section 3</button>

        <!-- Contents loaded from server is inserted here by javascript -->
        <div id="content">

        </div>
    
    </body>
</html>

 

Now open your terminal and run :

python manage.py runserver

 

Open the link http://127.0.0.1:8000/ in your browser and if everything worked out  good you should get something like this:

 

When you click on any of the buttons, it loads different text from the backend(Django) into the page without reloading the page. It loads the content very fast because it is running on a local server. If it were on a remote server, it will take some time before the contents appear.

The process of clicking a button to load content from the backend without reloading the page makes our app a single-page.

This is just a simple implementation. The texts being loaded from the backend could be a list of blog posts or some other data from a database, it could be anything.

 

You can find the code for this project on GitHub here.

 

 

 


Share This Post

Tweet Share Share Share

Subscribe to receive updates!

2 Comments

avatar

Mahin Kannan December 21, 2020

Hello, this is a nice and easy tutorial for creating a dynamic webpage. Single page application has a different meaning though. SPA's kinda auto update the webpage without reloading and without having to click any button. Example: Suppose there is some data that is displayed on the webpage from a database, if the backend or you change the data in the database, your frontend will automatically make the change on the webpage (user does not have to do anything). Frontend frameworks like React help achieve this functionality. So the title of this article while literally correct, is technically misleading.
.


avatar

PythonStacks December 22, 2020

I understand that a single page application is much more than what is provided here, but this tutorial is to give beginners some idea/concept of implementing a SPA in Django.
But do know that a SPA doesn't have to auto-update the page, it could be updating the page when an event occurs like clicking, scrolling, hovering over an element, etc


avatar

Derrick November 05, 2020

A great introduction to Django and Fetch, maybe follow it up with crud example.


Leave a comment

* Email would not published