This repository contains the code for the second class in Andrew Pinkham's Python Web Development series, titled Building Backend Web Applications and APIs with Django. The series is published by Pearson and may be bought on InformIT or viewed on Safari Books Online. The series is for intermediate programmers new to web development or Django.
Andrew may be reached at JamBon Software for consulting and training.
- Changes Made Post-Recording
- Technical Requirements
- Getting Started Instructions
- Walking the Repository
- Extra Problems
- Testing the Code
- Deploying the Code
- For security purposes a commit has been added at the end of every branch which secures the application using basic login functionality. The content of that commit will be discussed in the third Python Web Development class - I hope you're looking forward to it!
- Test dependencies have been included in all branches, so that the Docker image may be built once and used on all branches.
- The Docker image has been updated to use Python 3.7.1 (from 3.7.0)
- Pre-Commit and Black have been updated to more recent versions
- The site uses Django's
StaticFilesStorageinstead of theManifestStaticFilesStorageshown in Lesson 7 by error.
- Python 3.6+ (with SQLite3 support)
- pip 10+
- a virtual environment (e.g.:
venv,virtualenvwrapper) - Optional:
- Docker 17.12+ with Docker-Compose (or—if unavailable—PostgreSQL 10)
All other technical requirements are installed by pip using the
requirement files included in the repository. This includes Django 2.1.
For a full guide to using this code please refer to Lesson 2 of the class. This lesson demonstrates how to get started locally as well as how to use the Docker setup.
If you are unable to run Docker on your machine skip to the Local Setup section.
The use of Docker images allows us to avoid installing all of our dependencies—including PostgeSQL—locally. Furthermore, as discussed in the videos, it helps with parity between our development and production environments.
Our Docker containers expect the existence of an environment file. To
generate it on *nix systems please invoke the build_docker_env.sh
script.
./build_docker_env.shOn Windows please invoke the batch file.
build_docker_env
If you run into problems please refer to the videos for why we use this and what is needed in the event these scripts do not work.
To run the Docker containers use the command below.
docker-compose upIf you wish to run the servers in the background use the -d
(detached) flag, as demonstrated below.
docker-compose up -dTo turn off the server use Control-C in the terminal window. If running in the background use the command below.
docker-compose downTo remove all of the assets created by Docker to run the server use the command below.
docker-compose down --volumes --rmi localThe --volumes flag may be shortened to -v.
Use pip to install your development dependencies.
$ python3 -m pip install -r requirements/development.txtIf you have checked out to an earlier part of the code note that you
will need to use requirements.txt instead of
requirements/development.txt.
You will need to define theSECRET_KEY environment variable. If you
would like to use PostgreSQL locally you will need to set
DATABASE_URL.
export SECRET_KEY=`head -c 75 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 50`
# replace the variables in <> below
export DATABASE_URL='postgres://<USER>:<PASSWORD>@<SERVER>:5432/<DB_NAME>'Please be advised that if you are running code in Lesson 2 you should expect to see errors. Lesson 2 changes the database structure but avoids making migrations until the very last moment. What's more, database settings change in Lesson 2.8. Errors are therefore normal!
To make perusing the code in this repository as simple as possible the
project defines its own .gitconfig file with custom commands
(aliases).
To enable the commands you must first point your local git configuration at the file provided. Either of the two commands below should work.
# relative path
git config --local include.path "../.gitconfig"
# absolute path - *nix only!
git config --local include.path "`builtin pwd`/.gitconfig"This will enable the following git commands:
git next: Move to the next example/commitgit prev: Move to the previous example/commitgit ci: shortcut forgit commitgit co: shortcut forgit checkoutgit st: shortcut forgit statusgit ll: shortcut forgit log --oneline
These commands can be used on any of the two branches in this repository, which are listed below.
class_material: contains the code and material seen in the videos, as well as solutions to exercises mentioned in Lessons 5 and 6 (see section below to review).with_tests: includes material above, as well as the tests used by me to verify the code works
At the end of Lessons 5 and 6 I leave you with several optional exercises.
In Lesson 5:
- Create new
NewsLinkobjects in API via POST method (ConsiderViewSetsvsAPIViewsubclasses) - Simplify
PostSerializerwithHyperlinkedRelatedField(as seen onNewsLinkSerializer) - Use
ViewSetsand Routers to simplify Post handling in API
In Lesson 6:
- Use
CreateView,UpdateView, andDeleteViewto create views forStartupandPostobjects (usingStartupFormandPostForm) - Create a view to create new
NewsLinkobjects and associate them automatically withStartupobjects - Expand this view to handle updating
NewsLinkobjects - Allow for
NewsLinkobjects to be deleted
Below are a few other tasks to test your knowledge.
- Create links in the templates to enable easier navigation across the site
- Create a welcome page for the API (see the use of
DefaultRouter)
The solutions to all of the tasks above can be found in the
class_material git branch or on Github.
All of the tests used to build the code can be found in the
with_tests branch on Github.
The branch (mostly) emulates a Test Driven-Development approach: commits
prefixed with test write a test that will fail, while commits with
lesson numbers then fix the failing tests from previous test commits.
To run the tests locally use manage.py.
# from root of project
cd src
python3 manage.py testTests may also be run in Docker.
# from root of project
docker-compose run --rm django python manage.py testBe advised that running tests in Lesson 2 is tricky. You will generally need to create migrations before being able to run the tests, and there are a few commits that break the project's ability to run tests (such as when changing the database settings).
We will cover material about how to test Django in the next Python Web Development class. I hope you're looking forward to it!
The project follows 12 Factor App principles and is configured to be deployed to Heroku.
To start you will need to sign up for Heroku unless you already have an account. Make sure you have installed the Heroku CLI.
The following instructions are for *nix systems, and will need to be adapted for Windows.
Ensure your app is ready for deployment.
docker-compose run --rm django python manage.py check --deploy --settings="config.settings.production"From the command line create a new app.
$ heroku createHeroku will give your app a random name (such as
infinite-tundra-77435). Assign this name to a variable to be able to use
commands below.
$ export APP='infinite-tundra-77435' # replace with your actual app nameYour git repository should now have a new remote branch named heroku.
If it is missing you can add it manually.
$ heroku git:remote -a $APPCreate a PostgreSQL database for your app.
$ heroku addons:create -a "$APP" heroku-postgresql:hobby-devConfigure your app to use production settings.
$ heroku config:set -a "$APP" DJANGO_SETTINGS_MODULE='config.settings.production'
$ heroku config:set -a "$APP" SECRET_KEY="$(head -c 75 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 50)"
$ heroku config:set -a "$APP" PYTHONHASHSEED=random
$ heroku config:set -a "$APP" WEB_CONCURRENCY=2You may now deploy your app.
$ git push heroku class_material:master
$ # you can also deploy the other branch to Heroku using:
$ git push heroku with_tests:masterTo create a new user use the command below.
$ heroku run -a $APP python src/manage.py createsuperuserTo access the remote shell (to create data on the fly) use the command below.
$ heroku run -a $APP python src/manage.py shell_plusTo see the app online you may use the command below.
$ heroku open -a $APPFor more about what we've just done please see Heroku's Getting Started with Python documentation. If Lesson 7 does not cover as much material as you'd like you may be interested in Chapter 29 of Django Unleashed.