Skip to content

Instantly share code, notes, and snippets.

@avinasha
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avinasha/39b06dc2116666af7e5c to your computer and use it in GitHub Desktop.
Save avinasha/39b06dc2116666af7e5c to your computer and use it in GitHub Desktop.

If you dont have a python env setup yet, follow the instructions in python_env.md.

Installing django

Setting up django for a new project

Installing django

Once your python env is setup: pip install Django==1.8.2

Create a new porject

django-admin.py startproject <name> This creates the following file structure

new_django
├── manage.py
└── new_django
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Run python manage.py runserver. You should see Starting development server at http://127.0.0.1:8000/.

Configure Django Env (Dev, Production, Staging maybe Testing later)

The dev, production or staging env differ from each other. Mainly they differ in 2 aspects

  • required packages (production might need a different web server)
  • settings (db connections, external services API keys)

Required packages pip can install packages from a requirements.txt. Create requirements.txt in the root directory (new_django... the outer one) and add Django to it

Django==1.8.2

pip install -r requirements.txt will verify and install all the dependencies. Now that we have a requirements.txt we need to split it up so we can have requirements for each envirnoment

$ mkdir requirements
$ touch requirements/{development.txt,production.txt}
$ mv requirements.txt requirements/base.txt

Let ".txt" files inherit from "base.txt"

$ cd requirements
$ echo "-r base.txt" | tee -a development.txt production.txt
$ cd ..

Now you can add env specific requirement into their respective files and run pip

$ pip install -r requirements/development.txt

Your directory structure after this step will look like:

new_django
├── manage.py
├── new_django
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── requirements
    ├── base.txt
    ├── development.txt
    ├── production.txt

Settings
Time to split up the settings.py.
$ mkdir new_django/settings

This folder will contain:

  • __init__.py file to make this folder a Python package
  • base.py will contain all the settings that are common in all environments. The other setting files inherit from this one.
  • development.py is for local development.
  • production.py will be used in the production environment. Let’s create these files, all inside the new_django/settings folder:
$ cd new_django/settings
$ touch __init__.py development.py production.py

And edit each of them to make them inherit from the base.py file:

# -*- coding: utf-8 -*-
from .base import *

And finally, we have to move and rename the settings.py file created by Django, to be our base.py file inside the settings folder. Working inside the settings folder, you have to type:

$ mv ../settings.py base.py

The folder structure after this step should be:

new_django
├── manage.py
├── new_django
│   ├── __init__.py
│   ├── settings
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── development.py
│   │   ├── production.py
│   ├── urls.py
│   └── wsgi.py
└── requirements
    ├── base.txt
    ├── development.txt
    ├── production.txt

Since we have moved the default setting module, we need to tell django where to find the new setting module through a ENV variable DJANGO_SETTINGS_MODULE. We can set this in the virtual env that we have created. We need to create a virtual env for each django env we want to support. In this example one for development (already present) and one for production.

With virtualenvwrapper, there is a way to configure different hooks that are sourced before or after activating the virtual environment, and before or after deactivating it. This means that we can define a set of statements that will be run at different stages of the virtual environment lifecycle. These hooks are saved inside the bin folder inside the virtual environment folder, and their names are preactivate, postactivate, predeactivate and postdeactivate.

In our case, we will set a postactivate script that will set the DJANGO_SETTINGS_MODULE variable just after activating the virtual environment, and a predeactivate that will clean it up before deactivating it. Assuming you have already created the dev virtual env (else run mkvirtualenv new_django_dev)

$ workon new_django_dev 
$ cd $VIRTUAL_ENV/bin

The last command will take you to the virtual environment folder, where the different hooks reside. Edit the postactivate file by adding:

export DJANGO_SETTINGS_MODULE="new_django.settings.development"

and edit the predeactivate file by adding:

unset DJANGO_SETTINGS_MODULE

Do the same with the production environment, with the only change:

export DJANGO_SETTINGS_MODULE="taskbuster.settings.production"

It’s time to check! Go back to the root folder and activate your development environment. Next, run:

 python manage.py runserver

and in the output displayed you should see a line indicating that you are using the new_django.developmentsettings file, something like:

Django version 1.8, using settings 'new_django.settings.development'

Now that we have different virtual env working, we can move the config DEBUG from base.py. DEBUG must be set to Flase in production. Add DEBUG = True in development.py and DEBUG = False in production.py. Remove DEBUG = True from base.py.

If you open the file new_django/settings/base.py you will see a variable named SECRET_KEY . This variable should be kept secret, and therefore out of version control.

One option would be to add the base.py file into the .gitignore file, that is, remove it from the version control. However, during project development this file suffers many changes, and it’s quite useful to have it in version control, specially if you want to share it with your coworkers. Therefore, a better approach is to remove the secret key variable and import it from somewhere else. And this somewhere else is the one that should remain out of version control.

The approach we will follow here is to put the secret key inside our virtual environment configuration, and get the key from the environment by importing it in the base.py file.

To include the secret key inside the virtual environment we will also work with the virtualenvwrapper’s postactivate and a predeactivate hooks.

Activate your new_django_dev environment and go to its bin folder using the shortcut

$ cd $VIRTUAL_ENV/bin

If you type ls you will see that it contains the files we just described. Edit the postactivate file and add the secret key line

export SECRET_KEY="your_secret_django_key"

Note: don’t put any spaces around the = sign. Next edit the predeactivate file and add the line:

unset SECRET_KEY

This way, if you type:

$ workon new_django_dev
$ echo $SECRET_KEY
your_secret_django_key
$ deactivate
$ echo $SECRET_KEY
-

Where the last line indicates that there is no output. This means that the variable SECRET_KEY is only visible when working in this virtual environment, as we wanted.

Repeat the same process for the new_django_production virtual environment. And finally, edit the base.py file, remove the SECRET_KEY and add the following lines:

from django.core.exceptions import ImproperlyConfigured
 
def get_env_variable(var_name):
    try:
        return os.environ[var_name]
    except KeyError:
        error_msg = "Set the %s environment variable" % var_name
        raise ImproperlyConfigured(error_msg)
 
SECRET_KEY = get_env_variable('SECRET_KEY')

The function get_env_variable tries to get the variable var_name from the environment, and if it doesn’t find it, it raises an ImproperlyConfigured error. This way, when you try to run your app and the SECRET_KEY variable is not found, we will be able to see a message indicating why our project fails.

Let’s check that it all works as expected. Save the base.py, deactivate both environments and activate them again, in different terminal tabs. Run the development server in the new_django_dev environment

$ python manage.py runserver
Install Postgres and Configure Django to use it

Follow instructions here: http://www.marinamele.com/taskbuster-django-tutorial/install-and-configure-posgresql-for-django

Install python verson manager

Install a python version manager: pyenv

Install python

pyenv install 3.4.3 User the installed python: pyenv local 3.4.3. This will create a .python-version in the current directory. Chunk this into your git repo so everyone in the team uses the same python version. You can also set the python version gobally using pyenv global 3.4.3

Install python virtualenv creator/manager

pyenv-virtualenvwrapper. This is based on http://pypi.python.org/pypi/virtualenvwrapper which helps in creating virtualenv (dev, testing) for your application. Once pyenv-virtualwrapper is installed, add the following lines to you bash_profile or zshrc

if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
export PYENV_VIRTUALENVWRAPPER_PREFER_PYVENV="true"
pyenv virtualenvwrapper

Open a new shell window or source ~/.zshrc in your currently open shell.

Create and set virtualenv

Create: mkvirtualenv <name>
Set: workon <name>

Install pip

Follow instructions here: https://pip.pypa.io/en/stable/installing.html

Run pip

Run pip only after setting the virtualenv. All the requirements will only be installed in the set virtual env pip install -r requirements.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment