A high-performance movie discovery platform built with Django REST Framework, capable of searching and filtering 300,000+ records in real time. Features background data ingestion via Celery + Redis, a containerized Docker setup, and a responsive React.js frontend.
- π Smart Search API β Multi-parameter filtering by title, language, genre, rating, and release year
- β‘ High Performance β DB indexed fields + optimized QuerySets on 300,000+ records
- π Background Tasks β Celery workers fetch TMDB data without blocking the API
- β° Scheduled Jobs β Celery Beat auto-updates movie data on a schedule
- π Pagination β Offset-based pagination for safe browsing of large datasets
- πΌ Smart UI β Auto-hides movie cards when poster images are missing
- π³ Fully Dockerized β One command starts the entire 6-service stack
- π± Responsive Grid β 4-column movie layout built in React.js
| Layer | Technology |
|---|---|
| Backend | Django, Django REST Framework |
| Frontend | React.js |
| Database | PostgreSQL 15 |
| Cache / Broker | Redis |
| Task Queue | Celery (Worker + Beat) |
| DevOps | Docker, Docker Compose |
βββββββββββββββ
β React.js β β Frontend (localhost:3000)
ββββββββ¬βββββββ
β HTTP
ββββββββΌβββββββ
β Django API β β DRF (localhost:8000)
ββββββββ¬βββββββ
ββββββββββββββββΌβββββββββββββββ
β β β
ββββββββΌβββββββ βββββββΌββββββ ββββββΌβββββββββββββββββββ
β PostgreSQL β β Redis β β Celery Worker β
β (Movies DB)β β (Broker) β β + Beat (Scheduler) β
βββββββββββββββ βββββββββββββ ββββββββββββββββββββββββββ
All 6 services β Django, PostgreSQL, Redis, Celery Worker, Celery Beat, Redis Commander β start with a single command.
| Service | Description | Port |
|---|---|---|
web |
Django REST API | 8000 |
db |
PostgreSQL 15 database | 5432 |
redis |
Message broker for Celery | 6379 |
celery_worker |
Processes background TMDB fetch tasks | β |
celery_beat |
Schedules periodic data sync tasks | β |
redis-commander |
Redis GUI for monitoring queues | 8081 |
git clone https://github.com/25punam/movie-api.git
cd movie-apicp .env.example .env
# Open .env and fill in your credentials.env should contain:
SECRET_KEY=your-django-secret-key
DEBUG=True
POSTGRES_DB=Movies
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-strong-password
DB_HOST=db
DB_PORT=5432
TMDB_API_KEY=your-tmdb-api-key
β οΈ Never commit your.envfile to GitHub. Make sure it is listed in.gitignore.
docker compose up --builddocker compose exec web python manage.py migrate| Service | URL |
|---|---|
| Django API | http://localhost:8000 |
| Redis Commander (GUI) | http://localhost:8081 |
The frontend runs separately from the Docker backend.
cd frontendnpm installnpm starthttp://localhost:3000
β οΈ Make sure the Docker backend is running before starting the frontend.
GET /api/search/
Query Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
q |
string | Search by title or overview | Inception |
language |
string | Filter by original language code | en, hi, fr |
genre |
string | Filter by genre name or ID (comma-separated) | Action or 28,12 |
min_rating |
float | Minimum vote average (0β10) | 7.5 |
release_year |
integer | Filter by release year | 2023 |
page |
integer | Page number (default: 1) |
2 |
limit |
integer | Results per page (max: 100) |
12 |
Example Requests
GET /api/search/?language=en&page=1&limit=12
GET /api/search/?q=inception&release_year=2010
GET /api/search/?genre=Action&min_rating=7.5&page=1
GET /api/search/?language=hi&genre=28,12&limit=20
Example Response
{
"movies": [
{
"id": 27205,
"title": "Inception",
"original_language": "en",
"release_date": "2010-07-16",
"vote_average": 8.4,
"popularity": 98.5,
"poster_path": "https://image.tmdb.org/t/p/w500/..."
}
],
"total_count": 312000,
"returned_count": 12,
"page": 1,
"page_size": 12,
"limit": 12
}Celery handles all TMDB data fetching in the background so the API stays fast and responsive at all times.
User hits API β Django responds instantly (no waiting)
Meanwhile in background:
Celery Beat (scheduler)
β
Triggers fetch task on schedule
β
Celery Worker fetches pages from TMDB API
β
Saves / updates 300,000+ records in PostgreSQL
docker compose exec web python manage.py shellfrom movies.tasks import fetch_movies
fetch_movies.delay()# Watch Celery worker logs
docker compose logs celery_worker -f
# Watch Celery Beat scheduler logs
docker compose logs celery_beat -fmovie-api/
β
βββ movie_api/ # Django project config
β βββ settings.py
β βββ celery.py # Celery app configuration
β βββ urls.py
β
βββ movies/ # Core Django app
β βββ models.py # Movie & Genre models with DB indexes
β βββ views.py # MovieSearchAPIView (DRF APIView)
β βββ serializers.py # DRF serializers
β βββ tasks.py # Celery tasks β TMDB data fetch
β βββ urls.py
β
βββ frontend/ # React.js frontend
β βββ src/
β βββ package.json
β
βββ docker-compose.yml # Orchestrates all 6 services
βββ Dockerfile
βββ requirements.txt
βββ .env.example # Environment variable template
βββ README.md
-
Database Indexing β
db_index=Trueapplied onmovie_id,title,original_language,popularity,vote_average, andrelease_datefields, enabling fast filtering and sorting across 300,000+ records without full table scans. -
Paginated Responses β Offset-based pagination ensures only one page slice hits the DB at a time (
queryset[offset : offset + page_size]), so 300,000+ records are never loaded into memory at once. Response size is capped at 100 items per request. -
N+1 Query Prevention β Used
prefetch_related("genres")to fetch all genre data in a single DB query instead of one query per movie row. -
Django Q Objects β Multi-field search runs across
titleandoverviewin a single optimized OR query, with.distinct()preventing duplicate rows caused by ManyToMany genre joins. -
Smart Default Limits β No-filter requests default to 100 results; filtered requests allow up to 500 β balancing performance with usability and preventing accidental rendering of 44,000+ records on a single filter.
-
Popularity + Rating Ordering β Results sorted by
-popularity, -vote_averageso the most relevant movies always appear first without any client-side sorting overhead. -
Celery Async Tasks β TMDB API data ingestion runs entirely in background Celery workers, keeping the Django API fast during large data updates. Celery Beat automates scheduled syncs.
-
PostgreSQL over SQLite β Production-grade database handles concurrent API requests and 300,000+ records reliably, with full support for indexing and complex multi-parameter queries.
-
Docker Volumes β PostgreSQL data persists in a named Docker volume (
postgres_db), so all 300,000+ records survive container restarts and full rebuilds safely.
# Stop all running containers
docker compose down
# Stop containers and delete all data volumes (resets the database)
docker compose down -v- Redis caching for frequent search queries
- Elasticsearch integration for full-text search
- Movie recommendation system
- JWT Authentication for user accounts
- CI/CD pipeline with GitHub Actions
- AWS ECS production deployment
MIT License β feel free to use and modify.