What at all is Django?

Django is a web framework developed for python web developers to have it easy developing fully functional and production ready web applications. It is called the framework for perfectionists with a deadline. Meaning if you need that web application up and running quickly, but still need it to be working well and be the best, then use django.


Django comes out of the box with database management, a fully functional and customizable  admin site. The web framework implements python's best practices and teaches beginner level python programmers how to organize their files for easy access and manipulation. 


Even the competent programmers who never really learnt how to organize their files grasp these  concepts just through one web app development with django. The framework has grown over the years so much that many packages have been developed around it to ease development such as packages for API (Django RESTful), social authentication, PWA, django_mysql, django online users, whitenoise and many others.


This makes development with django not just easy but fun and once you get the basic concepts,  you are good to go.  Its principles such as DRY (Don't Repeat Yourself) make development so smooth and easy for even up and coming developers.


What can you build with django?

Basically, any web application you can conceive can be built with django and even progressive 

web applications. Not leaving out web APIs. I have used it to build powerful web applications, like this one you are using now, this https://pharst.pywe.org, https://homescreen.pywe.org 

and others.

Requirements for the course

⌨ Basic knowledge of python is required. (Basic syntax declaration)

⌨ Functions in python

⌨ A snapshot of Model View Controller Architecture is good knowledge for this course

⌨ A general knowledge of programming is actually required.


Setting up django

In order to use django, you will need python, pip, and a virtual environment on your machine. We will go step by step into the details of installing these software on our systems. I will be considering two different systems primarily: Windows and Linux systems, if you use Mac, you could try out the instructions for Linux.


Windows Installation

Check for Python

The simplest way to test for a Python installation on your Windows server is to open a command prompt (click on the Windows icon and type cmd, then click on the command prompt icon). 


Once a command prompt window opens, type python and press Enter. If Python is installed correctly, you should see output similar to what is shown below:

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.

Note The part with 3.7.0 above depends on the python version installed on your system and therefore may differ. If you receive a message like:

Python is not recognized as an internal or external command, operable program or batch file.

This means either of two things:

  1. Python is either not installed  or
  2. The system variable path hasn’t been set.

For 1, You’ll need to either launch Python from the folder in which it is installed or adjust your system variables to allow Python to be launched from any location. For 2, We need to install python by ourselves.


Download Python

To install python on your windows, visit https://www.python.org and download python ( preferably, version 3.6 or more ), while installing, please make sure  you mark the global option and mark add Python to system PATH

These  will make sure it is installed across your computer, so you could run it from anywhere.

Now if you type python in your command line (please, close the command line and open again after the installation), it should show the appropriate python version you downloaded alongside some other messages as I said earlier

Now that we have python and probably PIP, let's make sure we have PIP.

Install pip

Usually Python3 comes with pip pre-installed. If you get an error "pip command not found", after typing "pip" in your command line then use the following 

steps to install pip:


Download get-pip.py (search for it), make sure you're saving the downloaded file to Desktop. In your Command Prompt navigate to Desktop like this:

cd Desktop

Execute get-pip.py like this:

python get-pip.py

Now pip should work system wide when you type pip in the command line

With that, we have 2 out of 3 of our system's requirements to install django. The third is virtualenv, let's get that too.


Installing Virtualenv

In your Command Prompt enter:

pip install virtualenv

That will get you the virtualenv package and after that we can now create a virtual environment so we start working.

Creating a virtual environment

open your command line if it's not already opened, and navigate to Desktop if you are not already there. We use cd (change directory) together with the destination directory name to navigate to that directory.

Like this:

cd Desktop

We then create a virtual environment by calling the installed virtualenv package together with a name we choose to give our virtual environment. Like this:

virtualenv myenv

The virtualenv package will create a new folder (which is our virtual environment folder) in the Desktop directory. After this creation, in order to enter our new environment, we need to activate it like this:

myenv\Scripts\activate

You should notice that "(myenv)" is now written just before the rest of the directory name in your command line.


Congratulations, Windows user, you have finished installing python, pip and virtualenv

Installing Django

Now that we have the system requirements, let's get django into our virtualenv which we created (named myenv) and activated. To get django, please type the following:

pip install django

This will get django into your virtual environment and this means if your virtual  environment is not activated, all codes using django will fail. That's no problem, just remember to activate your virtual environment before you start working anytime. The trick to know that it is activated is to check for "(name)" before the directories names in your terminal/command line.

We shall also install a package called whitenoise, this package will enable us to be able to serve static files for our website or web apps. Static files are those files that are not written codes; they usually include CSS, JS, Image files. 

To install whitenoise:

pip install whitenoise

Congratulations again, now we have our system setup to dive into django in the next tutorial.


Installation On Linux

Download Python

Linux systems usually come with python already installed on them. So first, check for the existence of python. Open up your terminal (CTRL + ALT + T, should do the trick) and type python3. Getting something like this:

Python 3.6.5 (default, May 11 2018, 13:30:17) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

Means you already have python version 3 on your machine.If not, use this commands to get python.

sudo apt-get install python3

Installing pip

sudo apt install python3-pip

The above command should get pip installed for you. To check for pip version, enter:

pip3 --version

Installing Virtualenv

In your terminal enter:

pip3 install virtualenv

That will get you the virtualenv package and after that we can now create a virtual environment so we start working.

Creating a virtual environment

open your command line if it's not already opened, and navigate to Desktop if you are not already there. We use cd (change directory) together with the destination directory name to navigate to that directory.

Like this:

cd desktop

We then create a virtual environment by calling the installed virtualenv package together with a name we choose to give our virtual environment. Like this:

virtualenv myenv

The virtualenv package will create a new folder (which is our virtual environment folder) in the Desktop directory. After this creation, in order to enter our new environment, we need to activate it like this:

source myenv\bin\activate

You should notice that "(myenv)" is now written just before the rest of the directory name in your command line.

Congratulations, Linux user, you have finished installing python, pip and virtualenv

What are Python, PIP and Virtualenv ?

Python

Python is a programming language used to tell a computer how to do certain tasks. An in depth treatment of python can be found on our python course.

PIP

PIP is a package managing tool for python, it is used to install python packages or codes written by other people so that we can use them in our codes. Django, Flask, among other big projects can be downloaded unto our local machine using PIP.

VIRTUALENV

This is used to create a whole new environment within our computer, it makes sure that whatever is happening within that environment does not affect the whole system. Think of it as a sound proof room, where you can enter and shout but no one within the main house will hear you. Packages that are installed here cannot be used without activating the environment. So you need to remember to always activate, not create, activate, your virtual environment anytime you decide to work on your project.

If it is active, you should see it's name like this (myenv) before the rest of the directory name.

 Installing Django

Now that we have the system requirements, let's get django into our virtualenv which we created (named myenv) and activated. To get django, please type the following:

pip3 install django

This will get django into your virtual environment and this means if your virtual  environment is not activated, all codes using django will fail. That's no problem, just remember to activate your virtual environment before you start working anytime. The trick to know that it is activated is to check for "(name)" before the directories names in your terminal/command line.

We shall also install a package called whitenoise, this package will enable us to be able to serve static files for our website or web apps. Static files are those files that are not written codes; they usually include CSS, JS, Image files. 

To install whitenoise:

pip3 install whitenoise

Congratulations again, now we have our system setup to dive into django in the next tutorial. 

We have downloaded python,pip and vitualenv. After that we created and activated a virtual environment, after which we installed django and whitenoise in that virtual environment. As I said earlier, you must always make sure that your virtual environment is activated in order to work with django (according to this django series), because we installed django only in the virtual environment and not system wide.

Deciding a new project.

We will not go through the typical steps of deciding and planning a project, that is another course. We will just decide a project and see how far we can go. The project I propose here is a news wepbapplication. 

News Web App

So what typically goes into an app like this? Well, a news web app will have users, it will have other users who can write and publish news (staff), it will have a page where one gets to see all the trending news, a page where one gets to read the details of one particular news. 

The news after creation should be updatable, or even deletable. We could even go to the extent of making users able to subscribe so that they get notified in their mails when news is published.

So basically, that's our project. I'm excited, I'm trying to imagine how our finished app will look like. I will list the things we will be doing in the app as list of objectives (just so that it looks like we planned the project), so that we can cancel out the things we have achieved and the things left to be achieved.

Objectives

  1. User management
  2. Staff management
  3. Homepage (this could be our news list page as well)
  4. News list page
  5. News detail page
  6. password management (change,forgotten passwords)
  7. And some other stuff

So those are our objectives right now for our news web application. I will be looking forward to creating or getting some nice logo and design concept for the application.

Creating A New Django Project

Please make sure your virtual environment is activated. We are naming the project Nounews (New News)


Windows users

Activate Virtual environment

cd Desktop
myenv\Scripts\activate

To create a new django project, type the following in the command line which is already opened and has your virtual environment activated.

django-admin startproject Nounews

After hitting enter, django has silently created a new project for you called Nounews on your desktop. This project has so many amazing things already setup for you. A functioning administration site, database connection settings, wsgi, and every other thing you need. All we will be doing is customizing the project to suit what we want to do.


So now, to enter your newly created project called Nounews and see if it's actually set up already do the following

cd Nounews
python3 manage.py runserver

You should see the following output or similar one:

Watching for file changes with StatReloader
Performing system checks...


System check identified no issues (0 silenced).


You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): 
admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.


December 08, 2019 - 19:43:36
Django version 2.2, using settings 'news_proj.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Open your web browser and type http://127.0.0.1:8000/ and see your django rocket about to take off !!!


Linux users

Activate Virtual environment

cd Desktop
source myenv/bin/activate

To create a new django project, type the following in the terminal which should be already opened and has your virtual environment activated.

django-admin startproject Nounews

After hitting enter, django has silently created a new project for you called Nounews on your desktop. This project has so many amazing things already setup for you. A functioning administration site, database connection settings, wsgi, and every other thing you need. All we will be doing is customizing the project to suit what we want to do.


So now, to enter your newly created project called Nounews and see if it's actually set up already do the following

cd Nounews
python3 manage.py runserver

You should see the following output or similar one:

Watching for file changes with StatReloader
Performing system checks...


System check identified no issues (0 silenced).


You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): 
admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.


December 08, 2019 - 19:43:36
Django version 2.2, using settings 'news_proj.settings'Starting development server at http://127.0.0.1:8000/Quit the server with CONTROL-C.

Open your web browser and type http://127.0.0.1:8000/ and see your django rocket about to take off !!!



Previously On Django.

In our previous sections, we looked at how to set up a django project from scratch: we downloaded python, installed pip, created and activated our virtual environments,

created a new django project called Nounews and even saw the django rocket in our browser all ready to take off. Yes, we are ready to take off now. We are ready to start customizing our django project to suit our need, that is, a news web application.

Applications In a Django Project

You could view the project(Nounews) as your whole web application, and within this web application will be different parts: accounts for registration, logging user activities, resetting passwords among others.

We could also have another part for managing our news, that is, creating, editing and updating, deleting, and viewing our actual news contents. 

These various sections (accounts,news, etc) are what we refer to in django as apps (applications).

So different apps will handle different parts of the whole web application but they will seamlessly work together on the same domain, in this case, our domain is our localhost: http://127.0.0.1:8000/. In a production case, your domain name could have been www.pywe.org.

So usually, when you see a url like this www.pywe.org/accounts/ the accounts part represents a particular application within the project, you would see something like www.pywe.org/accounts/login/ as the url for a login page. Meaning the login implementation has been handled under the accounts application. The login part would usually be directed towards a function in the views.py file which is located in the accounts application.

Applications make things intuitive

This separation does not only make things clearer but easier while working with the project, you are able to classify in your mind's eye where a certain business logic or implementation should take place and the overall sitemap or site structure for your website becomes very intuitive.

We will go on to creating our first application which will be called accounts as well for user management. I strongly recommend you create this as your first application in any django project unless of course there will be no need for user management at all.

Accounts for Nounews

For our project, we plan to at least have some people registered even if not as users, as people who can create content for our site. We will therefore implement an accounts app, which will take care of our user management. If later on we want our users to register to read our news, we could do that.


Now, let's get to code. Get back to your command line and do CTRL + C to stop the server running if it's still running.If you need to start your command line again, here are the steps


Windows

 At any point in time, if you want to understand your file structure,type "dir" (without the quotes) in the command line, it will list your folders and files and you will know where you are currently in your directories

At any point in time if you want to open your command line, Type cmd in your start menu and click on the command prompt when it pops up.


Then type:

cd Desktop (cd for change directory, This will take you to your desktop directory in the command prompt)


Then type:

myenv\Scripts\activate (To activate your virtual environment)


Then type:

cd Nounews (This will take you into the actual django project we created)

Now enter the following command to create a new application called accounts

python manage.py startapp accounts


Linux 

At any point in time, if you want to understand your file structure, type "ls" (without the quotes) in the terminal, it will list your folders and you will know where you are currently in your directories.

At any point in time ctrl + alt + t will open your terminal


Then type:

cd Desktop

Then type: 

source myenv/bin/activate (To activate your virtual environment)

Then type:

cd Nounews(This will take you into the actual django project we created)


Now enter the following command to create a new application called accounts

python3 manage.py startapp accounts

Everyone

With just that command, django has generated a new folder within your project root folder called accounts and within this new folder will be the following files and folder:

__init__.py

Another empty file required in our accounts folder to make the accounts folder importable in other parts of the application



admin.py

This will be used to control the admin part of our app on the admin site which currently run on our https://our_domain/admin



apps.py

A file you would not need to worry about, will contain the name of our app for migration purposes which happen under the hood, all taken care of by django.


models.py

This file will be used to define our database table structures all in the form of simple python classes. Django will handle the rest.


tests.py

This file is used to run tests on our application, we might or might not run any unit tests. We will still however test the project by it's use cases.


views.py

This may become our most edited file, we shall use this to control what is displayed to our users. This is where the business logic of our app will happen. Every work load will be done here, calculations, and other stuffs that need to be done before we show anything to our users will be done here.


urls.py

This file may not have been automatically generated by django for you, but we will create it ourselves in this folder to listen to requests that come in specifically to this part of the project. So basically requests that come in on http://domain/accounts/ will be listened to from here. Go ahead and create this file in the folder right now. It is our listener to any request made by our users. Create the file and name it urls.py


forms.py

Go ahead and create this file also, we shall be using it to define our HTML forms especially for our administration site.


Let's Start with User Accounts

Now, to begin with actually editing code, please open the project's folder in your favourite IDE, I will be using Visual Studio Code, you could download it too, it's light-weight and very elegant to work with. Or if you have pycharm, then open your project in it.

Look for the accounts folder, and look for models.py file inside the accounts folder. 

import Django's AbstractUser model so that we can override it. There's already an import in there like this:

from django.db import models

# Create your models here.


Add these lines so that your file now looks like this

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


# Create your models here.
class CustomUser(AbstractUser):
    pass

So, what are we doing here?

We imported django's AbstractUser model and then wrote a new class called CustomUser, we then made Django's AbstractUser model a parent class to our new class. This is because Django's AbstractUser model contains almost everything that a user model needs: username, password, email, first_name, last_name,... and so on. The ones that are not available we can simply add in place of the pass keyword there. We have the ability to even override certain attributes on the go. 

For example, if the email field is not null, meaning the user must always provide an email field for our database to validate and we do not want that, we could simply re-define the email field and set it's null to True.

We however used the keyword pass above to show that we want to retain all the definitions of the AbstractUser model for our CustomUser model for now. We can however customize later on when the need arises.

Changing Django's User Model

Django inherently knows that its own user model is the authentication user model; meaning django's user model is the default user model that is used to authenticate a user, but now that we want to have our own user model called CustomUser model, we would tell the project about it.

Open settings.py file; it is located in the folder named Nounews which is inside the root folder. Now add this line of code which will tell Django about our new user model.

AUTH_USER_MODEL = 'accounts.CustomUser'

Place it at the bottom of the settings.py file, it tells django to make CustomUser from accounts as our new AUTH_USER_MODEL.

What the Django Docs says about Custom User Models

Changing to a custom user model mid-project

Changing AUTH_USER_MODEL after you’ve created database tables is significantly more difficult since it affects foreign keys and many-to-many relationships, for example.

This change can’t be done automatically and requires manually fixing your schema, moving your data from the old user table, and possibly manually reapplying some migrations. See #25313 for an outline of the steps.

Due to limitations of Django’s dynamic dependency feature for swappable models, the model referenced by AUTH_USER_MODEL must be created in the first migration of its app (usually called 0001_initial); otherwise, you’ll have dependency issues.

In addition, you may run into a CircularDependencyError when running your migrations as Django won’t be able to automatically break the dependency loop due to the dynamic dependency. If you see this error, you should break the loop by moving the models depended on by your user model into a second migration. (You can try making two normal models that have a ForeignKey to each other and seeing how makemigrations resolves that circular dependency if you want to see how it’s usually done.)


The above is the reason why we need to do this first before we even run our first migrations.

Registering our application

We created a new application, but we need to tell the project about it, it doesn't just know that there is a new application until we register the application. In the file you just edited, settings.py, there is a line called INSTALLED_APPS = ... .Now, we need to add accounts in the list.

This is how it currently looks:

INSTALLED_APPS = [
    'django.contrib.admin',


    'django.contrib.auth',


    'django.contrib.contenttypes',


    'django.contrib.sessions',


    'django.contrib.messages',


    'django.contrib.staticfiles',


]

We will now edit it to look like this:

INSTALLED_APPS = [
    'django.contrib.admin',


    'django.contrib.auth',


    'django.contrib.contenttypes',


    'django.contrib.sessions',


    'django.contrib.messages',


    'django.contrib.staticfiles',


    'accounts',
]

Migrations

We can now peacefully effect this changes to our database. Django comes with a very easy database management tool called migrations. With this, your classes from models.py file are turned into sql tables with class attributes becoming the tables' columns. So, even though our CustomUser model does not have any fields now, we know that it inherited fields from AbstractUser model. The migration process is as follows:

We first makemigrations; this process is used by django to generate the commands it will use to actually execute our sql statements. Django will therefore create a migrations folder in  our application folder and migration files containing the commands to be executed at each point will be in this migration folder.

Secondly and finally we migrate; this process is used by django to actually create, modify, or delete our tables as defined in our models.py file.

So let's do these, go to your command line or terminal and run the following commands:

Windows

Type:

python manage.py makemigrations accounts

After which you will see:

Migrations for 'accounts':
  accounts/migrations/0001_initial.py
    - Create model CustomUser
Type:
python manage.py migrate accounts

After which you will see this:

Operations to perform:
  Apply all migrations: accounts
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying accounts.0001_initial... OK

Now type:

python manage.py migrate

After which you see:

Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, sessions
Running migrations:
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying sessions.0001_initial... OK


Linux

Type:

python3 manage.py makemigrations accounts

After which you will see:

Migrations for 'accounts':
  accounts/migrations/0001_initial.py
    - Create model CustomUser
Type:
python3 manage.py migrate accounts

After which you will see this:

Operations to perform:
  Apply all migrations: accounts
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying accounts.0001_initial... OK

Now type:

python3 manage.py migrate

After which you see:

Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, sessions
Running migrations:
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying sessions.0001_initial... OK

This is a special case, we migrated for accounts separately first in order to effect the changes we made to the User model and then we migrated the whole project to take care of any remaining migrations project wide. So, if you want  to migrate for a specific application and not the whole project, you add the name of the application.

Creating our first user

Now, if we run the server and tried going to our administration site, the site will ask for credentials we do not have, we have actually been locked out of our own project. So, we need to create a superuser who can login and then start adding other users and managing the site. To create that first user:

python3 manage.py createsuperuser

You will see the following, please while typing the password, it will not show anything, just know what you are typing

Username: TheoElia
Email address: theoeligh@gmail.com
Password: 
Password (again): 
Superuser created successfully.

It will ask you for a username, email and then password (twice). After successfully creating this user, please run your server like this:

python manage.py runserver

After which you should see something like this:

Watching for file changes with StatReloader
Performing system checks...


System check identified no issues (0 silenced).
December 17, 2019 - 08:55:22
Django version 2.2.3, using settings 'Nounews.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.


By now you should have noticed the command we are using to run everything, python manage.py, manage.py is a file located in the root folder of our project and also you may have noticed that python is called for Windows users but python3 is called for Linux users.

Administration site

Now that we have created the user, open your browser or another tab and go to http://127.0.0.1:8000/admin, login with the credentials you gave while creating the user. You should see a full administration site, ready for you.

CONGRATULATIONS !!!


You have successfully created an app, created a custom user management model, registered it and created yourself as a superuser of the site. These are the harder parts, the rest will be fun.

Next we will be adding our own homepage, looking at source control with git and solving some issues


Making our first HTML page

So far, we have not had our own page being displayed, we have been working on django's page. Now let's have our own pages. Let's begin with creating an HTML page, which will be our homepage. We will use it to replace the message displayed by django when we visit the homepage. This means, our page will show instead of django's congratulatory one.


Django has its own way of teaching you how to organise your files and folders and we are about to delve into something like that practically. Please pay keen attention to what we are going to do. Within your accounts folder, create a new folder and call it templates. Now, within that templates folder, create a new folder and call it accounts. Now within that accounts folder, create a file and call it index.html

So now if we want to open the index folder these are directories we would have to go through:

 Nounews/accounts/templates...

/accounts/index.html 

Within the index.html file, let's write some basic HTML, Welcome the user to our Nounews project. You could use this to do that and don't worry about the basic look now, we will get something more graphic later:

<html>
    <head>
        <title>Our News</title>
    </head>
    <body>
        <header>
        </header>
        <main>
            <h3>Welcome to Nounews</h3>
            <p>You are at the right place for your latest and hottest news!. We report as it happens.</p>
        </main>
    </body>
</html>

The above HTML has some tags that do not have any content within them yet, that is because we will work on those later. Let me take the opportunity to take you through each of these tags briefly:

<html>

The html element represents the root of an HTML document.


<head>

The head element represents a collection of metadata (descriptive data) for the Document.


<body>

The body element represents the content of the document.


<header>

The header element represents introductory content for its nearest ancestor sectioning content or sectioning root element. A header typically contains a group of introductory or navigational aids. When the nearest ancestor sectioning content or sectioning root element is the body element, then it applies to the whole page.


<main>

The main element represents the main content of the body of a document or application. The main content area consists of content that is directly related to or expands upon the central topic of a document or central functionality of an application.


Calling Our HTML in views.py

Now, let's configure our project to recognize the html page we just wrote.


We need to call the page we just wrote in our views.py, This is where we define the logic of what should be calculated or not, and finally be return to the user. Please head over to the views.py file and  let's begin:

Django has a render method (function), which can show a page or any data we want it to show. We will write a basic function in python and then call the index.html file we just wrote and then 

render(present) it to the user when the user visits a particular url within our project. That last part about the user visiting a particular url, we will implement in the urls.py I asked you to create earlier. So, if you have not created it, please do create a urls.py file in the accounts folder, where views.py is.


Now let's head over to views.py file located in accounts folder and add our function that will present the HTML page (index.html) that we just wrote to the user. In the views.py file, paste this code:

def index(request):
    template_name = "accounts/index.html"
    return render(request,template_name)

Paste it right under this: # Create your views here, so that your views.py file now looks like this:

from django.shortcuts import render


# Create your views here.


def index(request):
    template_name = "accounts/index.html"
    return render(request,template_name)

Now, as I said earlier, we need to define the url on which the user can view this page so let's head over to urls.py file which is right where views.py file is and add the following code:


from django.conf.urls import url,include
from accounts import views


urlpatterns = [
url(r"^$",views.index, name="home"),
]

Any request coming to a django project first goes to the project itself before it is redirected to a particular application like our accounts application. Therefore if you take a look at your project, you will find a urls.py file located where settings.py file is. This should be in the project's main folder. 

That file currently looks like this:

"""Nounews URL Configuration


The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path


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

Now, we are going to make very few changes to it. The first one, I want you to replace this line: 

from django.urls import path 

with this line: 

from django.conf.urls import url,include

The second, this is to replace this line: 

path('admin/', admin.site.urls), 

with this line: 

url(r"^admin/",admin.site.urls),

The last thing is not a replacement but an addition, add this line right after the line you just modified:

url(r"^$",include("accounts.urls")),

This will make your file look like this:

"""Nounews URL Configuration


The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.conf.urls import url,include


urlpatterns = [
    url(r"^admin/",admin.site.urls),
    url(r"^",include("accounts.urls")),
]

So, what did we do?

We are routing, or directing all requests that come to our site's url forward slash admin(http://127.0.0.1:8000/admin/) to django's admin page. That's what this line: url(r"^admin/",admin.site.urls), does. And then we are directing all request that come to our site's base url (http://127.0.0.1:8000), that is the raw url of our site without anything else added it to accounts.urls, that is, the urls.py file located in accounts and I hope you remember that we did something there earlier.

So basically, when a request comes to the project, it is redirected to the appropriate application's urls.py and then in that application's urls.py, an appropriate function from views.py of that application is called and then also in that function, appropriate calculations and validations are done and then we finally show the user the page they are looking for.

In this particular case, when someone visits our homepage, the request is redirected to the urls.py file we wrote in accounts folder and then the function we called index will be called upon from the views.py. This function will also finally call upon our index.html and the boom, our user has our homepage.




windows

python manage.py runserver 

Linux

python3 manage.py runserver


Now visit: http://127.0.0.1:8000/ or simply click view site from your admin dashboard if your admin is already opened. You should see what we wrote in the index.html file appearing as:


Welcome to Nounews

You are at the right place for your latest and hottest news!. We report as it happens.


Congratulations again !!!


Next, we will be working on the beauty and responsiveness of the homepage.

We decided to work on the beauty and responsiveness of our homepage, in a real life project, usually a template is used. A template is an already developed, usually very beautiful html outline which we can customize to our needs. In this project, we shall do the same, you will get the template on our Github page for this project. Download the templates and let's get to configuring it to our needs.

You may need a github account to be able to clone this project, git is a very good practice while working on projects like this so if you do not have a git account, please open a new tab and go to github.com, create an account and then get back here to continue.

Why Git?

Well, git is a very good programming practice, let me tell you my painful story to illustrate and make sure you don't end up having the same story.

I once wrote a Siri-like program on my phone in python, I mean a talking chatbot, which could send sms to people, reply sms, make calls, chat among other things, and this project was saved on my phone. One day, I went to write an Exam, when I came out of the Exam hall, someone had stolen my bag, which had my phone inside. I did not only lose my bag, my notes and my phone but this brilliant project, yes it was gone. I have not had the chance to even rewrite it, it will take a long time to do it again.

Now, I wouldn't have lost this project if I had it saved online somewhere, I would have just downloaded it on a new phone. That's just one of the painful stories of not storing my code online.

So git helps you store your code online, allows you to make changes to it from your local machine, and download it to other devices later on. It even allows others to copy that project, or work on it with you. Talking about copying (cloning projects), that's what we are going to do next.


We will be cloning this whole project, which as I said earlier, is available at our github page. The following are the steps to cloning this project to your own computer. You weren't told about this earlier in order to help you follow up all the setup steps as these steps are the most difficult in setting up a Django project. So the project you are about to clone already has the beautiful homepage we are trying to build.


What is cloning?

Cloning is the act of making a copy of a project which is online to your own computer offline. This allows you to have a copy of an online project on your own computer, you can then work on that project offline and push the changes back online when you are done. We are therefore going to use some basic git commands to copy the project from online.


Let's Clone The Project

After successfully creating your github account, go to the project page and click on the green  button with mouse pointer having the text "Clone or Download". Click on the button with the book and arrow pointing left to copy the project url.


Now go to your machine and open your command line or terminal and input the following:


cd Desktop or desktop
git clone https://github.com/pywe/Nounews.git Nounews-pywe

Notice Nounews-pywe was added, this is to copy the project into a folder called Nounews-pywe to prevent the project you are already working on from clashing with this one since they both have the same name. So actually, to clone a project, you only need git clone and the url of the project. If your terminal or command complained there is no git, do not worry get git by doing the following and the go back to clone the project.


For windows

Open a new tab and Google "download git". That should take care of you downloading and installing git on your machine. You can take a look at our GIT COURSE in order to understand simple usages.


FOR LINUX

sudo apt-get install git

Those should take care of git's unavailability.

Now, use the same command we used in trying to clone the project again.

What next?

After cloning the project, it is now a folder on your desktop called Nounews-pywe, in that folder, you have all the project files, as at now we are interested in only certain folders.

The first folder we are interested in is the static folder, so copy the whole static folder and paste it into your Nounews folder. The image below should give you an idea of the folder we are to copy. It is the highlighted one

The second folder we are interested in is templates, this can be found in Nounews-pywe/accounts/. There is an accounts folder inside Nounews-pywe, inside that accounts folder, there is a templates folder, copy it too and paste inside your accounts folder in your Nounews project. Doing that may ask for replacement of your old files, please accept the replacement. With that done, run your project (I believe by now you can do that all on your own) and see your Nounews homepage all setup.

My Homepage isn't beautiful, why?

If your page appears in raw html form without the nice graphics you see in the images presented, these are the things you should do.

Go to your settings.py file, which I believe you are now familiar with.

Look for Debug = True and change it to Debug = False

After that, look for ALLOWED_SITES = [] and change it to ALLOWED_SITES = ["*"], also

you should make sure that whitenoise has been added to you project, to do this, just go to your middlewares which is in your settings.py and looks like this:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...

]

and change it to look like this:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...

]

This means you are adding this line 'whitenoise.middleware.WhiteNoiseMiddleware', as the second line of the middlewares.

After doing this, you should also make sure that your STATIC_ROOT is set, in your settings.py file, put them on its independent line in the settings.py file like this:

STATIC_ROOT = os.path.join(BASE_DIR, "static")

These few steps should fix your problem, so simply restart your server and see your site come to live. Whitenoise is the one serving the static files (images, js, and css) for us and therefore requires us to put our project's debug value in production mode, which is False. 

Whenever our project is in production mode, then it needs to know which domains it should allow to access it, in a real production case, you domain name should therefore be in the ALLOWED_SITES, but since we are still on development server trying to simulate a production server, the * which stands for any domain will save us for now.

And also, copy the settings.py file which is located in the project you cloned which is Nounews-pywe/Nounews/settings.py and paste it in your original project folder Nounews/Nounews. It will ask for replacement which you should grant. 


Enjoy the look, browse through and get familiar as we discuss in the next module what and what was put in place for this to happen. See you there!

From our previous module, we had a beautiful news homepage, showcasing some headlines, it included other sections that described the homepage and Nounews basically. Now, let's dive into how all of this was done.

Static Files

If you open up the static folder, you will see that there are folders of stylesheets, js, images,fonts and others. All these files, define the colors, shape, size,animation and responsiveness (making the page adjust well to different devices: mobile, tablets and desktops) of the page, you may not have to worry about these file unless you want to make some changes like color theme changes or add some other custom styles.

templates in accounts folder

The files we have to actually look at are located in the templates folder we copied. Within this templates folder, there is another folder called accounts and in this accounts folder, we have base.html and index.html. Now please, pay particular attention to this part as this is where our presentation to users of our site is done, the first page our users will see when they visit so mistakes will not be overlooked.


base.html

Looking carefully through this file, you should notice three things.

The first one is that, we have the head tag, called all css files and also brought the header. This first part defines all the css files that we are going to be using, the head tag gives descriptive data about the site to search engines and the header defined the navigation bar located at the top of our Nounews homepage.


The second thing you should notice is the django template tags:

{% block content %}
{% endblock content %}

The above template tag is used to hold down a place for the actual body html that will be coming from other pages. You will fully understand this part soon, please hold on.


The third part you should have noticed is footer and js files. The footer defines the bottom of the homepage.

Let me fulfill my promise: Now, in Django, we use base html to define parts of our pages that won't be changing even if other parts do change. You will notice most website have the same navigation bar (the top part of the page) when you browse from page to page and also that they have the same footer (the bottom part of the page). So, in order not to be rewriting these parts of the page for example when we want to write a registration and login page for our users, we write one base.html page, and then import it or in other words extend it when we want to write other pages.


index.html

The index.html page actually defines the content of our homepage, but I'm sure the first weird thing (that is if you are new to Django) you saw was the extension part. What we are doing on the first two lines of this page is to tell the system that we want this page to be added to our base.html page. So, all that we write in index.html will just be inserted at base.html, but where does base.html insert this so that our page isn't messed up, since HTML is highly structured? Well remember the second thing in base.html? 

I'm referring to the above, so we basically tell the system, by putting the same thing above around all the content we want to be inserted from index.html into base.html. If you get this right, this is the kind of image you may have of the whole process:

We defined head and bottom in base.html because they are piratically static, and then our other pages are used to define the body which is then inserted in-between the head and bottom defined in base.html.

We then call on the index.html from our index view found in views.py:

from django.shortcuts import render


# Create your views here.
def index(request):
    template_name = "accounts/index.html"
    args = {}
    return render(request,template_name,args)

The call to display our index.html page is what you see on line 5 of the views.py and this index view is called in urls.py of accounts.py as below:

from django.conf.urls import url, include
from . import views


urlpatterns = [
    url(r'^$', views.index,name="home"),
]

Which is saying that if our user goes to our homepage, we should call the index views which will also render the index.html page which also calls on base.html for help with navigation bar and the footer. Isn't it beautiful. If this was helpful, give it a 5 star rating. Rating helps to improve upon the lesson, please leave your comments as well if you know rating won't help us get your message.

That is all about what we did to make our homepage beautiful instead of the one we wrote in the beginning.