Skip to content

Repository files navigation

🎓 LearnNow — Learning Management System

A production-style course marketplace backend built with Django REST Framework.

Teachers publish paid courses, students browse, buy, enrol, learn, and earn certificates — all through a clean, documented, JWT-secured REST API.

CI CodeQL Python Django DRF PostgreSQL JWT Stripe Deployed on Render License

Live API · API Docs (Swagger) · Report a Bug


📑 Table of Contents


🧭 Overview

LearnNow is the backend for an online learning platform in the style of Udemy or Coursera. It exposes a REST API that a separate frontend (a React / Vite single-page app) consumes to deliver the full learning experience.

The system supports three roles — Learners, Tutors (Teachers), and Admins — and covers the complete lifecycle of a course: authoring, publishing, discovery, purchase, enrolment, progress tracking, certification, reviews, and course Q&A.

It was built as a capstone project to demonstrate end-to-end backend engineering: modular app design, authentication, payments, media handling, relational data modelling, and API documentation.


✨ Features

👩‍🎓 For Students

  • Register, log in, and manage a profile with an avatar
  • Browse and search a catalog of courses by category, level, and language
  • Add courses to a cart, apply coupons, and check out via Stripe
  • Enrol in purchased courses and stream video lessons
  • Track lesson-by-lesson completion and earn a certificate on completion
  • Take personal notes, rate & review courses, and maintain a wishlist
  • Ask questions on a course through threaded Q&A

👨‍🏫 For Teachers

  • Create, update, and structure courses into sections (variants) and lessons
  • Auto-computed video durations on upload (via moviepy)
  • A dashboard with earnings, best-selling courses, student lists, and orders
  • Create and manage discount coupons
  • Receive notifications for new orders, reviews, and questions

🔐 Platform

  • JWT authentication with access/refresh tokens (rotation + blacklisting)
  • Role-based custom user model (email as the login identifier)
  • Interactive Swagger / ReDoc API documentation
  • CORS configured for a decoupled frontend
  • Themed Django admin for internal management

🛠 Tech Stack

Layer Technology
Language Python 3.12
Framework Django 5.2
API Django REST Framework 3.16
Auth JWT — djangorestframework-simplejwt
Database PostgreSQL (psycopg2-binary)
API Docs drf-yasg (Swagger / ReDoc)
Payments Stripe · PayPal
Media processing moviepy / imageio-ffmpeg
Config environs / python-dotenv
CORS django-cors-headers
Admin UI django-jazzmin
Server / Hosting Gunicorn on Render

🏗 Architecture

LearnNow uses a modular Django layout — a project package (learning/) plus one focused app per bounded context. Each app owns its own models, serializers, views, and URLs, and apps reference one another through Django's string-based model references to keep coupling loose.

learning-management-systems/
├── manage.py                # Django management entrypoint
├── requirements.txt
├── learning/                # Project config (settings, root URLconf, WSGI/ASGI)
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
│   └── asgi.py
├── users/                   # Custom user model, auth, profiles
├── teachers/                # Teacher profiles, coupons, dashboards
├── courses/                 # Courses, curriculum, reviews, notes, wishlist
├── carts/                   # Cart, orders, checkout
├── certificates/            # Enrolment, lesson completion, certificates
├── question_answer/         # Course Q&A threads
├── notifications/           # In-app notifications
├── static/  / staticfiles/  # Static assets (dev / collected)
└── media/                   # User-uploaded files (images, videos)

App responsibilities

App Responsibility
users Custom User (email login, Learner/Tutor/Admin roles) and UserProfile. Registration, login, profile, password change, logout, JWT issue/refresh.
teachers Teacher profile (1:1 with a user) and Coupon. Teacher dashboard: earnings, best sellers, students, reviews, orders, coupons, notifications.
courses Catalog core: Category, Courses, Variant, VariantItem, Note, Review, WishList, Country. Search, detail, create/update; auto video-duration.
carts Cart, CartOrder, CartOrderItem. Cart management, order creation, tax/coupon totals, Stripe checkout.
certificates EnrolledCourse, CompletedLessons, Certificate. Enrolment, progress tracking, certification, student dashboard.
question_answer QuestionAnswer and QuestionAnswerMessage threads on a course.
notifications Notification records for order/review/question events.

Request flow

Client (React SPA)
      │  HTTPS + Bearer JWT
      ▼
learning/urls.py  ──►  <app>/urls.py  ──►  DRF APIView / ViewSet
      │                                          │
      │                                    <app>/serializers.py
      ▼                                          ▼
drf-yasg Swagger UI                        <app>/models.py ──► PostgreSQL

🗃 Data Model

High-level relationships between the core entities:

  • A Teacher belongs to a User; a Teacher authors many Courses.
  • A Course has many Variants (sections), each with many VariantItems (lessons).
  • A Student (User) adds Courses to a Cart, which becomes a CartOrder of CartOrderItems at checkout.
  • A paid order item creates an EnrolledCourse, against which CompletedLessons and a Certificate are tracked.
  • Students leave Reviews and open QuestionAnswer threads on a Course.
User ──1:1──► Teacher ──1:N──► Course ──1:N──► Variant ──1:N──► VariantItem
 │                                │
 │                                ├──1:N──► Review
 │                                └──1:N──► QuestionAnswer ──1:N──► QuestionAnswerMessage
 │
 └──► Cart ──► CartOrder ──1:N──► CartOrderItem ──► EnrolledCourse ──► CompletedLessons / Certificate

📡 API Reference

All endpoints are served under /api/. Full request/response schemas are available in the interactive docs.

Area Base path
Auth & users /api/
Courses /api/v1/courses/
Carts & orders /api/v1/carts/
Certificates & enrolment /api/v1/certificates/
Teacher dashboard /api/v1/teachers/
Q&A /api/v1/qa/
Django admin /admin/
Swagger UI /
ReDoc /redoc/

Authentication. Obtain a token pair at /api/login/ (or /api/token/), send it as Authorization: Bearer <access>, and refresh at /api/token/refresh/. Access tokens live 30 minutes; refresh tokens 7 days (rotated and blacklisted on use).

Example: register and log in
# Register
curl -X POST http://127.0.0.1:8000/api/register/ \
  -H "Content-Type: application/json" \
  -d '{"full_name":"Ada Lovelace","username":"ada","email":"ada@example.com","password":"secret123"}'

# Log in → returns { "access": "...", "refresh": "..." }
curl -X POST http://127.0.0.1:8000/api/login/ \
  -H "Content-Type: application/json" \
  -d '{"email":"ada@example.com","password":"secret123"}'

# Call a protected endpoint
curl http://127.0.0.1:8000/api/profile/ \
  -H "Authorization: Bearer <access-token>"

🚀 Getting Started

Prerequisites

  • Python 3.12+
  • PostgreSQL
  • FFmpeg (required by moviepy for video-duration processing)

Installation

# 1. Clone
git clone https://github.com/omonuj/learning-management-systems.git
cd learning-management-systems

# 2. Virtual environment
python3 -m venv venv
source venv/bin/activate          # Windows: venv\Scripts\activate

# 3. Dependencies
pip install -r requirements.txt

# 4. Configure environment (see below), then:
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Then visit:


🔑 Environment Variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True

# PostgreSQL
DB_NAME=learnnow
DB_USER=postgres
DB_PASSWORD=yourpassword
DB_HOST=localhost
DB_PORT=5432

# Payments
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
PAYPAL_CLIENT_ID=...
PAYPAL_SECRET_ID=...

# Frontend
FRONTEND_SITE_URL=http://localhost:5173

⚠️ The app exits on startup if the Stripe/PayPal keys or FRONTEND_SITE_URL are missing.


☁️ Deployment

Configured for Render (see ALLOWED_HOSTS / CORS_ALLOWED_ORIGINS in learning/settings.py) and served with Gunicorn:

python manage.py collectstatic --noinput
python manage.py migrate
gunicorn learning.wsgi

🧩 Project Status & Roadmap

This is an actively developed capstone project. Known items to harden before true production use:

  • Restrict CORS — CORS_ALLOW_ALL_ORIGINS is currently True alongside the allow-list
  • Ensure DEBUG is falsy in production environments
  • Serve static files via WhiteNoise or a CDN instead of Django
  • Add automated tests and CI
  • Complete PayPal checkout flow alongside Stripe

👤 Author

Jonah Odoh


📄 License

Distributed under the BSD License. See the API schema metadata for details.


⭐ If you find this project useful, consider giving it a star!

About

A Django REST Framework backend for an online course marketplace — JWT auth, Stripe payments, course enrolment, progress tracking, and certificates.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages