Finn's Notebook

Building and deploying a Django web app to Heroku

Install packages:

pip install django-heroku
pip install django
pip install heroku

Create a folder for the project,
initialize the project within that folder:

django-admin startproject <project name>
cd <project name>
python3 manage.py startapp <web app name>

This will create a skeleton structure with the files you need.
The 'project' folder serves the website, it can coordinate multiple apps.
The 'web app' folder is where we build our web app.

<folder name> <--- reduce this redundant folder
    <project_name>/
        manage.py   <-- use to run project
        <project_name>/ 
            __init__.py
            settings.py
            urls.py     
            wsgi.py
        <web_app_name>/
            admin.py
            apps.py
            models.py
            tests.py
            views.py
            __init__.py
            migrations/
            templates/ <--create this folder
                index.html <-- place index in here

Within settings.py add a pointer to the web app,
for Heroku we also add an import and instantiate the django_heroku module:

import django_heroku
#----

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'web_app_name',
]

#---bottom of file---

django_heroku.settings(locals())

Edit urls.py to point to the web app:

from django.contrib import admin
from django.urls import path, include

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

Create a new urls.py in the web app folder:

from django.urls import path
from web_app_name.views import IndexView
print('urls loaded')
urlpatterns = [
    path('', IndexView.as_view() , name='index'),

]

Now within views.py we reference index.html:

from django.views.generic import TemplateView
from django.shortcuts import render
from django.http import HttpResponse

class IndexView(TemplateView):
    template_name = 'index.html'

    def get(self, request):
        return render(request, self.template_name)

#--- and to start developing interactivity ---

#    def post(self, request):
#        response = request.POST
#        return render(request, 'index.html', response)

This should be enough to deploy to Heroku.
Create an account at Heroku and initialize a new app.
Within the project folder initialize a new git instance.
Link it with the Heroku app.

heroku login
git init
heroku git:remote -a <heroku_app_name>

Create a file in the root project folder called 'Procfile'
Fill it like this:

web: gunicorn <project_name>.wsgi --log-file -

One method to tell Heroku what packages to run is with a requirements.txt file.
Another is build a virtual environment to test locally and export the requirements:

pipenv install gnuicorn Django requests #<all the packages used in the project>
pipenv lock #this creates pipfile.lock that heroku will use to install the environment

Now we can push to heroku to deploy.

git add .
git commit -m "first upload"
git push heroku master

Some packages require seperate libraries.
Heroku will need a Buildpack.
Create a file in the projects root folder named 'Aptfile',
fill it with the required libraries, one per line. Then run these commands:

heroku buildpacks:add --index 1 heroku/python
heroku buildpacks:add --index 2 https://github.com/heroku/heroku-buildpack-apt.git     

During the build phase you'll want to test the files locally:

python manage.py runserver