markdown
This is a robust Django application template featuring Django REST Framework, Simple JWT for authentication, Docker and Docker Compose for containerization, Celery for asynchronous task processing, Redis as a message broker and result backend, and comprehensive logging capabilities. It provides a production-ready setup for building scalable and secure RESTful APIs.
- 🛠️ Django REST Framework (DRF) for building powerful and flexible APIs
- 🔐 Simple JWT for secure JSON Web Token authentication
- 🐳 Docker & Docker Compose for consistent and reproducible environments
- 🥕 Celery for handling asynchronous tasks with Redis as the broker and backend
- 📜 Logging with structured output to console and file for debugging and monitoring
- 🗄️ PostgreSQL as the default database
- 🚀 Gunicorn for production-ready WSGI server
- 🔍 Environment Variables management with
.envfile - 📝 Pre-configured settings for development and production
Ensure you have the following installed:
- Python (v3.11 or higher)
- Docker and Docker Compose
- Git
- Clone the repository:
git clone <repository-url>
cd <repository-folder>- Copy the example environment file and customize it:
cp .env.example .env- Update .env with your desired settings (e.g., database credentials, secret key, Redis URL). Build and start the Docker containers:
docker-compose up --buildThis starts the following services:
web: Django application with Gunicorncelery: Celery worker for asynchronous tasksredis: Redis for Celery broker and backenddb: PostgreSQL database
To run the Django development server locally (outside Docker): Create and activate a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activatepip install -r requirements.txtpython manage.py migrate
python manage.py runservercelery -A config worker --loglevel=infoOpen http://localhost:8000 to access the API.
This template uses Simple JWT for authentication. To obtain a token:
- Send a POST request to /api/token/ with valid user credentials:
curl -X POST http://localhost:8000/api/token/ -d "username=<username>&password=<password>"- Use the access token in the Authorization header for protected endpoints:
curl -H "Authorization: Bearer <access_token>" http://localhost:8000/api/protected/Refresh tokens can be obtained via /api/token/refresh/.
To test Celery tasks, create a task in myapp/tasks.py (example included):
from celery import shared_task
import logging
logger = logging.getLogger(__name__)
@shared_task
def example_task(x, y):
logger.info(f"Computing {x} + {y}")
result = x + y
logger.info(f"Result: {result}")
return resultCall the task from a view or shell:
from myapp.tasks import example_task
example_task.delay(2, 3) # Runs asynchronously- Logging is configured to output to both console and a file (logs/app.log). Logs include:
- Django application logs
- Celery task logs
- Custom application logs
- To view logs:
Docker: Use docker-compose logs (e.g., docker-compose logs web).Local: Check logs/app.log or console output.
Example log configuration in config/settings.py:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': 'logs/app.log',
'formatter': 'verbose',
},
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'': {
'handlers': ['file', 'console'],
'level': 'INFO',
'propagate': True,
},
},
}- Update .env for production (e.g., DEBUG=False, strong SECRET_KEY).
- Build and start containers:
docker-compose -f docker-compose.yml up --build -ddocker-compose exec web python manage.py migratedocker-compose exec web python manage.py collectstatic --noinputThe application will be available at http://localhost:8000.
The docker-compose.yml file defines the following services:
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- .:/app
- static:/app/static
ports:
- "8000:8000"
env_file:
- .env
depends_on:
- db
- redis
celery:
build:
context: .
dockerfile: Dockerfile
command: celery -A config worker --loglevel=info
volumes:
- .:/app
env_file:
- .env
depends_on:
- redis
- db
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
env_file:
- .env
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
static:
Project Structure
├── .env.example # Example environment variables
├── .gitignore # Git ignore file
├── Dockerfile # Docker configuration
├── docker-compose.yml # Docker Compose configuration
├── logs/ # Log files directory
│ └── app.log
├── manage.py # Django management script
├── config/ # Django project settings
│ ├── __init__.py
│ ├── settings.py # Project settings (includes logging, Celery, JWT)
│ ├── urls.py # Project URL configuration
│ ├── wsgi.py
│ └── asgi.py
├── myapp/ # Sample Django app
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations/
│ ├── models.py
│ ├── tasks.py # Celery tasks
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── requirements.txt # Python dependencies
└── README.md # Project documentation
django@5.1.3: Web framework
djangorestframework@3.15.2: REST API toolkit
djangorestframework-simplejwt@6.1.0: JWT authentication
psycopg2-binary@2.9.10: PostgreSQL adapter
gunicorn@23.0.0: WSGI server
celery@5.4.0: Asynchronous task queue
redis@5.0.8: Redis client
python-dotenv@1.0.1: Environment variable management
`docker-compose up --build`: Build and start containers
`docker-compose down`: Stop and remove containers
`python manage.py runserver`: Start Django development server
`python manage.py migrate`: Apply database migrations
`python manage.py collectstatic`: Collect static files
`celery -A config worker --loglevel=info`: Start Celery worker
`docker-compose logs <service>`: View logs for a serviceDockerfile
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN pip install --upgrade pip
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN mkdir -p /app/logs && chown -R nobody:nogroup /app/logs
USER nobody
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "config.wsgi:application"]Simple JWT: Configured for token-based authentication
Celery: Uses Redis as broker and backend (CELERY_BROKER_URL, CELERY_RESULT_BACKEND)
Logging: Outputs to console and logs/app.log
Database: PostgreSQL via environment variables
REST Framework: Includes authentication and permission classes
Example .env.example:
DEBUG=True
SECRET_KEY=your-secret-key
DATABASE_URL=postgres://user:password@db:5432/dbname
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/0
ALLOWED_HOSTS=localhost,127.0.0.1
Fork the repository.
Create a branch: git checkout -b feature/your-feature.
Commit changes: git commit -m "Add your feature".
Push to branch: git push origin feature/your-feature.
Open a pull request.
MIT License. See LICENSE. This template is designed for rapid development and deployment of Django REST APIs. For issues or feature requests, please open an issue in the repository.
-
Security Policy Integration:
- The
SECURITY.mdfile is tailored to the Django template, specifying supported Django versions (5.1.x and 4.2.x, as 4.2 is the latest LTS version as of June 2025). - I replaced the generic email placeholder (
<your-security-email@example.com>) with a note to customize it. You should specify a real email or contact method for vulnerability reports. - The policy includes coordination with upstream projects (e.g., Django) and references to dependency security advisories.
- The
-
README Updates:
- Added a Security section linking to
SECURITY.md. - Updated the Project Structure to include
SECURITY.md. - Added a note in the Contributing section about security contributions.
- Kept all other sections consistent with your original Django template request.
- Added a Security section linking to
-
Assumptions:
- I assumed Django 4.2.x is supported as it’s the latest LTS version, while 5.0.x is not supported (as it’s not an LTS and likely superseded by 5.1.x).
- If you have specific version support preferences or a different contact method for vulnerabilities, let me know, and I can adjust the files.
-
Next Steps:
- Create a
SECURITY.mdfile in your repository with the content above. - Update your
README.mdwith the provided version. - Specify a security contact email in
SECURITY.md. - Ensure your repository includes a
LICENSEfile if you’re using the MIT License.
- Create a