When we create a project, Django provides us a secret key to use for different purpose in the project. That secret key is written in settings.py file. However, Django informs us to hide that key because when we push our Django project to a public repository on GitHub, people can see it.

 

# settings.py

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

One way to hide that secret key is to create an environment variable file “.env” in which we could define an environment variable with this key as the value. Doing so, we could use that variable in settings.py file instead of the key itself.

 

# .env

SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

To extract the value of the secret key, we could use getenv( ) method in python-dotenv package. So, we need to install this package.

 

$ pip install python-dotenv

 

We have to bare in mind that every time we install a new package, we need to update requirements.txt file to inform Heroku to install the same package for our Django app on its platform.

 

$ pip freeze > requirements.txt

 

To extract the value of the secret key, we could import python-dotenv as below:

 

# settings.py
...
from dotenv import load_dotenv  
load_dotenv()
...
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv('SECRET_KEY')

 

As the result, the secret key is hidden in .env file. We expose only its variable SECRET_KEY in settings.py module. And we must keep this .env file in our local machine by not pushing it to GitHub. To prevent .env file from being pushed to GitHub, we have to create .gitignore file next to .env file in our Django project.

 

# .gitignore

/.env

 

As the .env file is not being pushed to GitHub, a problem will happen on Heroku platform because the method getenv( ) will not find this .env file,  “Internal Server Error” will occur. Luckily, Heroku helps us to solve this problem by providing us a place in the application settings to directly define environment variables. And Heroku will looks for environment variables on its platform rather than in .env file.

 

 

For database, Heroku gives us many choices to choose database for our Django app such as MySQL, PostgreSQL, MariaDB, MongoDB etc. For this tutorial, we will use Heroku's PostgreSQL database by adding it to our Django app on Heroku. If we want to use this database on our local machine, we must create an environment variable DATABASE_URL with the link to Heroku's PostgreSQL as its value. We can find this link in the application settings on Heroku.

 

# .env

SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
DATABASE_URL=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

However, we have to keep in mind that for security reason, Heroku will change the link to the database very often. And it will not cause any problem for our Django app on Heroku, the problem happens only on our local computer. To solve this problem, when the link to the database is changed, we need to copy the new link to replace the old one in .env file.

 

Having the link to the database is not enough to use Heroku database, we need to set this database as the default database for Django app. This requires the use of dj-database-url package and PostgreSQL driver.

 

$ pip install dj-database-url
$ pip install psycopg2

 

$ pip freeze > requirements.txt

 

To connect to Heroku's database, we add the code below under the DATABASES section.

 

# settings.py
...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

import dj_database_url
DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)
...

 

Once connected to Heroku's database, if we run Django local server by typing “python3 manage.py runserver”, the sever will ask us to migrate or create necessary tables in the database.

 

You have 18 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.

 

And if we type “python3 manage.py migrate” on Terminal window, Django will create those tables in Heroku's database.

 

$ python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... 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 auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

 

To push our modified Django project to GitHub, we can do as below:

 

$ git add .
$ git commit -m "Make it better"
$ git push origin master

 

Heroku will  automatically copy this project from GitHub to build and install on its platform.

 

GitHub: https://github.com/Sokhavuth/khmerweb-django

Heroku: https://khmerweb-django.herokuapp.com