PART 2 - PROJECT & ENVIRONMENT SETUP

Django Series Part 2 - Project and development Environment Setup

Yasin Yusuf

works @ TecKave

Simple human being, Passionate Technophile, Coder, Entrepreneur who loves Art and Snakes

Published: September 25, 2019 Time: 11 min read

We talked about what django is and why you should consider it in the part 1 of this tutorial series. In this post we will answer this question “how to setup a django project from scratch?” we will learn about installing django and how to organize a django project.

Introduction

In this tutorial, I assumed you know that django is a python web framework, if you read the previous post you probably do, we also hoped you used command line before, if you didn’t read up on the commands in the list bellow. We will go through installing django and few other dependencies required to get your project up running.

Things to get familiar with

  • Commands

    • cd
    • ls
    • rm
    • mkdir
  • Concepts

    • Modularity
    • Environment Variables

Set up

What we will need to setup django project.

  • Python
  • Pipenv
  • Git
  • Database
  • Code Editor

Python

Django can be used with python 2 or python 3, but I wouldn’t recommend python 2 as it is getting terminated by 2020. We will use python 3.6.x for this project.

$ python -V
Output: Python 3.6.8

if your output says 3.6.x you good to go. If you have an older version of python, there are amazing tutorials on how to install newer version go look it up.

Pipenv

Pipenv is a packaging tool for Python that solves some common problems associated with the typical workflow. It solves the problem of having two different tools for package installation and virtaulenv. It also solves the pain of maintaining requirements.txt file. You can read up on pipenv in this post or checkout the docs.

Git

We will use Git and Github for version control. if you are new to version control systems or git this post goes in detail about them.

$ git --version
Output: git version 2.23.0

if you have 1.x or older please install newer version something like 2.x.

Database

Its rare to see application that doesn’t work with some sort of data in this day and age. In this project we will use PostgreSQL as a database. If you don’t have postgres installed on your system read this tutorial. We will setup the database for this project in a minute.

Code Editor

You can use whatever editor you want, django doesn’t have opinion about that. if you don’t have a code editor or you just starting out, I would recommend Sublime text 3.

Now that we have what we need to start the project. lets get started…

Project Setup

Project Directory

Every project needs a folder. Let’s create one. Navigate to where you put your projects with the cd command. then make a directory(folder) with the mkdir command.

$ cd Projects
$ mkdir local_book_store
$ ls
Output: local_book_store

If you have other project in that directory you might see them in the list with newly created folder.

Virtaulenv

Before we install anything lets setup virtualenv for the project. Make sure you are in the project directory.

$ cd local_book_store
$ pipenv --python 3.6
Output:

Creating a virtualenv for this project…
Pipfile: /home/username/Projects/Blog/local_book_store/Pipfile
Using /usr/bin/python3.6m (3.6.8) to create virtualenv…
⠹ Creating virtual environment...Already using interpreter /usr/bin/python3.6m
Using base prefix '/usr'
New python executable in /home/username/Envs/local_book_store-rkvcCW33/bin/python3.6m
Also creating executable in /home/username/Envs/local_book_store-rkvcCW33/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /usr/bin/python3.6m

✔ Successfully created virtual environment!
Virtualenv location: /home/username/Envs/local_book_store-rkvcCW33
Creating a Pipfile for this project…

This command will create not only virtualenv but also a file called Pipfile which keeps track of the project dependencies.

Note: this command uses the folder name for virtualenv name

To activate the virtualenv run this command in project folder where the Pipfile is:

$ pipenv shell

Installing Packages

Now we are finally ready to install django, psycopg2-binary for postgres database connection, path-py for dealing with paths.

$ pipenv install django path-py psycopg2-binary

Starting Django Project

With django installed now we are ready to ask django to put together a project for us! remember django has so many functionalies built in to it.

$ django-admin startproject local_book_store

Now if we look in to our folder we will see that django created a folder and few python files for us.

└── local_book_store
    ├── local_book_store
    │   ├── local_book_store
    │   │   ├── __init__.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   └── wsgi.py
    │   └── manage.py
    ├── Pipfile
    └── Pipfile.lock

Though there is nothing wrong with this structure, but there is always a room for improvement. Let’s re-arrange the folder structure to more comfortable way. To do that we need to understand what every file does. settings.py as the name describes it is the project settings file, where you keep things like your database, middlewares, manage apps(django apps) in your project, we will consider this settings file as common project file, because settings will be different when we developing the project than when we deploy to production. urls.py is where all routing happens, in other words its the file you keep project wide(common) urls. wsgi.py its the WSGI ( Web Server Gateway Interface ) file, we will explore this file more in the deployment section of the series. if you want to read up on it you can start with it’s docs. manage.py is a command line utility for administrative task, things like create applilcations, running development server. Finally __init__.py is a file required to make Python treat the directories as containing packages. Pipfile, Pipfile.lock are the files that pipenv created for us.

After fixing up the directory structure now our folder tree should look like this:

└── local_book_store
    ├── apps
    ├── __init__.py
    ├── manage.py
    ├── Pipfile
    ├── Pipfile.lock
    ├── settings
    │   ├── common_settings.py
    │   ├── development_settings.py
    │   └── __init__.py
    ├── urls.py
    └── wsgi.py

Its more maintainable and easy to navigate now. All of the settings will be in folder. the common file like urls.py, wsgi.py , manage.py, and Pipfiles are in the root folder. I created empty apps directory that all the apps we create will be under.

Note: this project directory structure is how we like to structure django projects at Teckave. The way you structure your projects is entirely upto you, but for this tutorial I will stick with this structure.

Getting the project running

Out of the box if you go into the folder that django generated and run the server the project will work fine, but since we moved files around we need to fix the code. Before we start doing that, we need to understand how django projects work. The main file in the project is the settings file. We moved and renamed the file so now if we try to run the project there will be an error from django saying “I am confused! I don’t know which settings file to use or where to find it”. To help django get out of the confusion we need to tell it where and which file to use, we do that by using environment variable called DJANGO_SETTINGS_MODULE which django looks for when starting a project. To set this env variable run:

$ export DJANGO_SETTINGS_MODULE='settings.development_settings'

with this command we are telling django to look for a settings folder inside our project directory and in that it can find the development settings we will write in a moment.

Lets start with settings/common_settings.py:

"""
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os
import sys
from path import Path as path


# This is creating the project path
PROJECT_PATH = path(__file__).abspath().realpath().dirname().parent
# This is creating django apps path
APPS_PATH = PROJECT_PATH / "apps"

# Adding our project and apps path to the system path
sys.path.append(PROJECT_PATH)
sys.path.append(APPS_PATH)


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'pewk#1qzkxnd9xh+_eoaj@jy&znvpv&9lfk#gw-h2q*%azy=mp'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition
# This tuple will contain built in django apps
# and the third party apps we will install
EXTERNAL_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

# The apps we create for the project
INTERNAL_APPS = ()

MIDDLEWARE = [
    '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',
]

# We change this, to reflect on where we moved the url.py file.
ROOT_URLCONF = 'urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# We change this, to reflect on where we moved the wsgi.py file.
WSGI_APPLICATION = 'wsgi.application'


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

Now it’s time for the development settings. In the settings/development_settings.py put this code:

from .common_settings import *

# For better debugging
# This is only for development
DEBUG = True

# Database
# You can change the name, user, and password if you want to
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": "local_book_store",
        "USER": "localbookstoreuser",
        "PASSWORD": '123',
        "HOST": "localhost",
        "PORT": "",
    }
}

# These are the third party apps that
# we need in the development process
DEVELOPMENT_APPS = ()

# This is the variable that django looks for
# to know about the apps that the project uses.
INSTALLED_APPS = EXTERNAL_APPS + DEVELOPMENT_APPS + INTERNAL_APPS


# Media files / the files that we upload
MEDIA_ROOT = os.path.join(PROJECT_PATH, "media")
MEDIA_URL = "/media/"

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(PROJECT_PATH, "static")]

To learn more about django settings head over to the docs.

Fixing up the manage.py file.

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    # See, Django is protecting us, if we forget to the set
    # the env variable it will use this default settings.
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.developemt_settings')
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

We also need to fix up wsgi.py file.

"""
WSGI config for local_book_store project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.developemt_settings')

application = get_wsgi_application()

Now that we fix the code, it is time to setup the database.

Database Setup

Postgres provides a terminal tool called psql that will facilitate the database interactions for us.

$ sudo -u postgres psql

This will ask you to type your password if you set it in the installation process. Once you are in the shell run these commands to create the db.

CREATE DATABASE local_book_store;
CREATE USER localbookstoreuser WITH PASSWORD '123';
GRANT ALL ON DATABASE local_book_store TO localbookstoreuser;
\q

Django migrations help us sync the database with the schema we already have. Lets ask django to setup the db for us.

$ python manage.py migrate

If you forgot to set the DJANGO_SETTINGS_MODULE you will get an error so make sure its set. Django comes with administrative area but doesn’t have a default user so we need to create it. manage.py will help us do that:

$ python manage.py createsuperuser

this command will ask you info about the user. so fill it up.

Starting the project

Finally, we can start up our development server!

$ python manage.py runserver
Output:
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
September 20, 2019 - 19:21:45
Django version 2.2.5, using settings 'settings.development_settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

If you got this output you are good to go. Head over to your web browser and visit http://127.0.0.1:8000/. You should see the django welcome page.

Congrats! you just setup and started django project! At this point you should award yourself with cup of really good coffee.

If you have any questions, use the comments section below, we will help you. If you liked this post spread the knowledge and consider joining us. We will notify you for freebies and more posts. Click here to be part of us

Share on LinkedIn
Share on Whatsapp