Django Website Part 2: How I create basic HTML, CSS pages

Modified: Dec. 2, 2021, 12:49 p.m.

Created: Dec. 2, 2021, 11:19 a.m.


Now you have set up the Django project, we can create and style pages for our website. In this blog, I will guide you on how to prepare basic static pages and how to add static files such as images and CSS.


Setting up basic pages

Let's start with a very basic home page.

Templates

Django uses Django HTML Template language to pass data from views to the front-end. This template language is a superset of HTML. In other words, normal HTML can be perfectly usable as Django Templates.

Let's start by creating a separate app for our home page. Modularizing project into apps makes our life easier. In the terminal,

$ python manage.py startapp home

Now you should get a directory named home in the project directory. To let our project know we have added a new app, the name of the app should be included in our settings.py's INSTALLED_APPS list.

INSTALLED_APPS = [
    'home',

    ...  # Other apps
]

Let's create a very basic home page. With the default settings, it is easier to have relevant template files inside your app as templates > APP_NAME > TEMPLATE_FILES. So let's create templates/home/home-page.html file inside our home app. The directory structure should look like this at the end.

home
├── admin.py
├── apps.py
├── __init__.py
├── models.py
├── migrations
│   └── __init__.py
├── templates
│   └── home
│       └── home-page.html
└── views.py

Now in home-page.html file, we can write any HTML.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div>
        <section>
            <h1>Hello Django!</h1>
            <p>How are you?!</p>
        </section>
    </div>
</body>
</html>

Configuring URL

Now we have to tell Django that to use this template file when we type in our web address. That is http://127.0.0.1:8000/. What comes next after the host address (in our case the host address is 127.0.0.1:8000) is called the path or subdirectory. When we request a page with a given path from our Django server, it does some pattern matching and checks if it has implemented some view for the requested path. For the home page, the path is '' because the path is empty. If we request http://127.0.0.1:8000/contacts/, it tries to match a view for the path 'contacts/'. If the server cannot find a view for that path, it returns a 404 error, which I am sure you have seen before.

But wait,

When we request http://127.0.0.1:8000/, it still returns a page without an error even though we haven't configured any URL yet. That is because, by default, Django returns its own pre-implemented home page to show when DEBUG is set to True.

So let's say Django that we want to show our own page when we type in home URL. Open views.py inside the home app. Add the following method.

from django.shortcuts import render


def home_page(request):
    return render(request, 'home/home-page.html')

Create urls.py file inside the home app. Add the following lines.

from django.urls import path

from . import views


urlpatterns = [
    path('', views.home_page, name='db-home'),
]

Now we have created a URL pattern inside the home app. We can give each end-point (URL) a meaningful name. You may realize the importance of that later. Here I named our home URL with db-home. The prefix db is because our project name is Django Blogs. You can name it with whatever you want. This URL name is only for the project. It is not visible to end-users.

Now let's tell our Django project to include this list of URL patterns of our home app. Open DjangoBlogs/urls.py file and include the patterns as follows. Don't forget to add relevant imports.

from django.urls import path, include


urlpatterns = [
    path('', include('home.urls')),

    ...  # Other patterns
]

Now if all is good, when you request http://127.0.0.1:8000/ from your browser, you should see the content of your HTML file.

Adding static content

Images

In Django, apps can have their own static files relevant to its pages such as images and CSS files. Static files are not supposed to belong to data held by any model. Similar to templates, they also live inside static/APP_NAME/STATIC_FILE path. When the server is serving static files, they have to be inside a separate directory that contains static files which we defines by STATIC_ROOT in settings.py.

Let's configure static file probing and static file directories inside our settings.py. Add these lines at the end of settings.py file.

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

This tells Django to find static files inside directories named static which is inside apps. Django copies these static files and folders inside apps to another project level directory that is defined by STATIC_ROOT in the previous step. I personally use the name staticfiles as opposed to popular name static for less confusion.

Technically, we can serve any file as a static file. I personally like to keep images in img, CSS in css, JavaScript in js directories. Download this or any other image and save it inside home app as home/static/home/img/1.jpg. The directory structure should look like this.

home
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   ├── __init__.py
├── models.py
├── static
│   └── home
│       └── img
│           └── 1.jpg
├── templates
│   └── home
│       └── home-page.html
├── tests.py
├── urls.py
└── views.py

Let's include the image in our home-page.html template file. To indicate that we are using static files inside a specific template file, we need to load tags (same as importing modules in python). For that, add the following line at the top of home-page.html.

{% load static %}

Now, add the <img> tag inside the <section> tag as follows.

<div>
    <section>
        <h1>Hello Django!</h1>
        <p>How are you?!</p>
        <img src="{% static 'home/img/1.jpg' %}">
    </section>
</div>

This tells Django to generate the URL of the static image we have given (static/home/1.jpg) it. And then render the HTML file inside the server and send it to the end-user.

If all is good, you should see this when you reload the website.

Preview - 1

CSS Stylesheets

Adding CSS stylesheets is done in pretty much the same way as adding images. Let's create a directory named css inside the home static directory and add a file named 1.css. It is known that having multiple CSS files for multiple pages is bad due to caching issues. The best practice is to create a single CSS file common to all pages that has all the CSS rules in it. We will get there in a later tutorial blog. For now, let's not dwell on such advanced details.

After adding the file, the home static directory should look like this.

static
└── home
    ├── css
    │   └── 1.css
    └── img
        └── 1.jpg

Now we can write CSS rules inside 1.css. Let's add very simple CSS rules for now.

h1 {
    color: red;
}

p {
    color: blue;
}

Pretty ugly CSS! I know :P.

Now let's tell our home-page.html to include our newly composed CSS file. Add this line inside the <head> tag.

<link rel="stylesheet" href="{% static 'home/css/1.css' %}">

Now we can refresh the webpage to see updates as follows.

Preview - 2

Great! In the next tutorial blog, I will guide you on how to set up Tailwind CSS as our CSS framework. Then we will be able to create more aesthetically pleasing websites.