# Setup Drf Project

> Create or guide creation of a modern Django REST Framework project with JWT auth, a custom User model, PostgreSQL through DATABASE_URL, django-environ, CORS, .env files, Docker, and validation commands. Use when the user asks to scaffold, bootstrap, initialize, or configure a DRF backend/API project with Simple JWT, Docker, PostgreSQL, or an accounts/me endpoint.

- Skill: `lopesmauro/setup-drf-project` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add lopesmauro/setup-drf-project`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lopesmauro/setup-drf-project/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: lopesmauro (https://skillmd.com/u/lopesmauro)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/lopesmauro/setup-drf-project

---


# Setup DRF Project

## Workflow

Use this skill to create a new DRF backend in the current directory or to carefully adapt an incomplete project. Prefer the bundled script for new or mostly empty directories:

```bash
python /home/mf/.codex/skills/setup-drf-project/scripts/setup_drf_project.py .
```

When the backend lives in a `backend/` directory, run the script from that directory or pass that directory as the target. The generated project is isolated and owns its local development infrastructure:

```txt
backend/
├── database/
│   └── Dockerfile
├── docker-compose.yml
├── Dockerfile
└── ...
```

Use `--force` only after inspecting the target directory and confirming overwrites are intended:

```bash
python /home/mf/.codex/skills/setup-drf-project/scripts/setup_drf_project.py . --force
```

The script creates:

- `core/` Django project files
- `apps/accounts/` with a custom `User`, admin, serializer with password hashing, authenticated user CRUD, `MeView`, URLs, and migrations package
- backend files: `.env`, `.env.example`, `.gitignore`, `requirements.txt`, and `Dockerfile`
- architecture decision records under `docs/adr/`
- local infrastructure files: `database/Dockerfile` and `docker-compose.yml` inside the backend directory
- split settings for development and production, django-environ, PostgreSQL, DRF, Simple JWT, CORS, default authenticated permissions, page-number pagination, `AUTH_USER_MODEL`, Portuguese/Brazilian locale, and `America/Manaus`
- production-ready defaults: Gunicorn container command, `.dockerignore`, console logging, production security settings, and `GET /api/health/`

If `docker-compose.yml` already exists in the backend directory, inspect it and add only the PostgreSQL `db` service pointing to `./database/Dockerfile`, plus the `postgres_data` volume if missing. Preserve existing services and do not rewrite the whole compose file unless the user explicitly asks.

## Manual Fallback

If the script cannot be used, perform the same steps incrementally:

1. Install dependencies:

```bash
pip install django djangorestframework djangorestframework-simplejwt "psycopg[binary]" django-environ django-cors-headers
```

2. Start the project before creating app files:

```bash
django-admin startproject core .
mkdir -p apps
touch apps/__init__.py
mkdir -p apps/accounts
python manage.py startapp accounts apps/accounts
```

3. Configure `apps/accounts/apps.py` with `name = "apps.accounts"`.
4. Create `apps/accounts/models.py` with `User(AbstractUser)` and unique `email`.
5. Register `CustomUserAdmin` in `apps/accounts/admin.py`.
6. Replace the generated `core/settings.py` with a `core/settings/` package before migrations:
   - `core/settings/base.py`
   - `core/settings/development.py`
   - `core/settings/production.py`
   - `core/settings/__init__.py`
7. Configure settings:
   - import `environ` and `timedelta`
   - read `BASE_DIR / ".env"`
   - use `SECRET_KEY = env("SECRET_KEY")`, `DEBUG = env("DEBUG")`, `ALLOWED_HOSTS = env.list(...)`
   - add `rest_framework`, `rest_framework_simplejwt`, `corsheaders`, and `apps.accounts.apps.AccountsConfig`
   - put `corsheaders.middleware.CorsMiddleware` before common/session middleware
   - set `AUTH_USER_MODEL = "accounts.User"`
   - set `DATABASES = {"default": env.db("DATABASE_URL")}`
   - configure `CORS_ALLOWED_ORIGINS`, `REST_FRAMEWORK`, and `SIMPLE_JWT`
   - set DRF pagination with `DEFAULT_PAGINATION_CLASS = "core.pagination.DefaultPagination"`, `PAGE_SIZE = 10`, and `MAX_PAGE_SIZE = 100`
   - configure production security settings in `production.py`
   - configure console logging
8. Update `manage.py` and `asgi.py` to default to `core.settings.development`; update `wsgi.py` to default to `core.settings.production`.
9. Update `core/urls.py` with admin, `GET /api/health/`, Simple JWT token endpoints, and `path("api/accounts/", include("apps.accounts.urls"))`.
10. Add `core/pagination.py` with a `DefaultPagination` class using `page_size_query_param = "page_size"` and `max_page_size` from settings.
11. Add `core/views.py` with an unauthenticated `HealthCheckView`.
12. Add `serializers.py`, `views.py`, and `urls.py` for `GET /api/accounts/me/` and authenticated user CRUD under `/api/accounts/users/`; restrict the user CRUD viewset to admin users.
13. Add backend files: `.env`, `.env.example`, `requirements.txt`, `.gitignore`, `.dockerignore`, and `Dockerfile`.
14. Add ADRs under `docs/adr/` documenting the backend architecture, isolated Compose decision, and production-readiness settings.
15. Add `database/Dockerfile` inside the backend directory.
16. Add or update the backend `docker-compose.yml`; if it already exists, add only the `db` service that builds from `./database/Dockerfile` and the `postgres_data` volume if missing.

Always inspect existing files before replacing them. Preserve unrelated existing code and report any conflict instead of deleting it.

## Validation

Run validation only after `AUTH_USER_MODEL` and `INSTALLED_APPS` are correct:

```bash
python manage.py makemigrations
python manage.py migrate
python manage.py check
```

For Docker:

```bash
docker compose up --build
```

Optionally create a superuser:

```bash
python manage.py createsuperuser
```

## Endpoint Checks

After the server is running and a user exists, test JWT:

```bash
curl -X POST http://localhost:8000/api/auth/token/ \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "admin"}'
```

Use the token:

```bash
curl http://localhost:8000/api/accounts/me/ \
  -H "Authorization: Bearer ACCESS_TOKEN_AQUI"
```

List users:

```bash
curl http://localhost:8000/api/accounts/users/ \
  -H "Authorization: Bearer ACCESS_TOKEN_AQUI"
```

Create a user:

```bash
curl -X POST http://localhost:8000/api/accounts/users/ \
  -H "Authorization: Bearer ACCESS_TOKEN_AQUI" \
  -H "Content-Type: application/json" \
  -d '{"username": "user1", "email": "user1@example.com", "password": "change-me"}'
```

Update and delete use `/api/accounts/users/<id>/` with `PUT`, `PATCH`, or `DELETE`.

Health check:

```bash
curl http://localhost:8000/api/health/
```

## Reporting

At the end, summarize files created or changed, validation results, commands to run the project, and the two curl examples above. If migrations or Docker are not run, state exactly why.

Also mention the generated ADR path and summarize the decisions it records.

