A Django course listing app, built while learning Django. Visitors can browse and search courses, view course details, and leave ratings or comments. Signed-in users can publish courses and manage their own listings. Available places are reduced when an enrolment is accepted.
The app uses Django templates and the ORM. Local development uses SQLite; hosted production deployments use PostgreSQL.
- Register, sign in, and sign out
- Create, edit, and delete your own course listings
- Browse recent courses, search, paginate, and view details
- Enrol in a course, with duplicate and capacity checks
- Leave a course comment or rating while signed in
- Manage course enrolments in Django admin
Open the repository root in PyCharm and configure a Python 3.12 interpreter. From a PowerShell terminal in the repository root, create and activate a virtual environment, then install the dependencies:
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txtIf PowerShell blocks activation, select .venv\Scripts\python.exe as the
project interpreter in PyCharm and run the remaining commands in its terminal.
Apply migrations and start the development server:
cd src\course_listing
python manage.py migrate
python manage.py createsuperuser
python manage.py runserverOpen http://127.0.0.1:8000/. The local database is src/course_listing/db.sqlite3.
It is ignored by Git and is not changed by the deployment workflow. Existing
course rows keep a blank owner through the migration; assign an owner in Django
admin if those older rows need to be editable by a signed-in user.
.github/workflows/django.yml runs on pushes and pull requests targeting
main, and can also be started manually. It installs the project dependencies,
runs Django's configuration check, checks that model changes have migrations,
and runs the Django test suite from the correct project path.
After a successful run on main, the workflow calls Render only when the
repository secret RENDER_DEPLOY_HOOK_URL is configured. Pull requests never
trigger a deployment. The secret contains the private URL generated by Render;
do not commit it to the repository.
The root render.yaml and build.sh configure a Render web service. To activate
hosting:
- Create a Render Blueprint from this GitHub repository and select
main. - Set
DATABASE_URLto a PostgreSQL connection string in the Render service. The app intentionally refuses to start in production without a database URL. - Copy the Render deploy hook URL into the GitHub repository secret
RENDER_DEPLOY_HOOK_URLunder Settings → Secrets and variables → Actions. - Run the Django CI and deploy workflow manually on
main, or push a commit after CI passes.
Render generates DJANGO_SECRET_KEY for the service. DJANGO_DEBUG is disabled
for hosting, and the app reads its Render hostname automatically. The build
collects static files and applies database migrations before starting Gunicorn.
The Blueprint uses Render's free web service for a no-cost preview. Free web services have an ephemeral filesystem and can sleep while idle. Render's free PostgreSQL database expires after 30 days. Use a durable PostgreSQL plan before relying on the site for persistent course or enrolment data. Uploaded course photos are stored on the service filesystem, so they also need persistent disk or external object storage for lasting hosted use.
src/course_listing/ Django project and courses app
.github/workflows/ GitHub Actions CI and optional deploy trigger
build.sh Render install, static collection, and migrations
render.yaml Render web service Blueprint
requirements.txt Python dependencies
The original tutorial references that inspired the project: