A beginner-friendly yet production-aware Django REST API for managing blog posts, users, authentication, and API documentation. The project demonstrates how to build a clean REST backend with Django, Django REST Framework, custom user models, token/session authentication, and OpenAPI schema generation.
This backend application provides a simple blogging platform API where:
- authenticated users can create, read, update, and delete blog posts
- each post is linked to its author and the author is auto-assigned when the post is created
- only the author of a post can update or delete it
- admin users can manage users through DRF viewsets
- authentication and registration are handled via
dj-rest-auth - API documentation is available through DRF Spectacular
It is designed as a learning project, but structured with production-level concerns in mind (environment management, deployment notes, security, database, and API design).
- Django 6 + Django REST Framework API
- Custom user model (
CustomUser) extendingAbstractUser Postmodel with title, body, author, created/updated timestamps- ViewSet-based API endpoints for posts and users
- Auto-assign
authoron post creation and permission control so only authors can edit/delete their posts - Session + token authentication support
- Registration and auth endpoints via
dj-rest-auth - OpenAPI schema and Swagger/Redoc views
- Basic Django test coverage for the post model
- list all posts and create new blog posts
- fetch, update, and delete individual posts
- user management endpoints
- authentication endpoints for login/logout/password workflows
- interactive API documentation
The project uses a custom user model instead of Django's default user.
| Field | Type | Purpose |
|---|---|---|
name |
CharField |
Optional display name for the user |
inherited username, email, password, is_active, etc. |
Django auth fields | Standard authentication fields |
This custom model allows the application to evolve without being tied to Django's default user structure.
The main content model for blog articles.
| Field | Type | Purpose |
|---|---|---|
title |
CharField(200) |
Post title |
body |
TextField |
Post content |
author |
ForeignKey to AUTH_USER_MODEL |
Links each post to the creating user |
created_at |
DateTimeField(auto_now_add=True) |
Timestamp when the post was created |
updated_at |
DateTimeField(auto_now=True) |
Timestamp when the post was last updated |
- One
CustomUsercan create manyPostrows. - Each
Postbelongs to exactly one author. - Deleting a user cascades to their posts (
on_delete=models.CASCADE).
The project uses a custom DRF permission class:
IsAuthorOrReadOnly- safe methods (
GET,HEAD,OPTIONS) are open to everyone - unsafe methods (
POST,PUT,PATCH,DELETE) require authentication - only the post author can update or delete their own post
- safe methods (
The user management API uses IsAdminUser, so only admins can manage users.
This creates a simple authorization model that mirrors a real blog backend:
- readers can browse posts
- authors can manage their own content
- admins can manage user accounts
blog API by book/
βββ README.md
βββ requirements.txt
βββ .venv/ # local virtual environment
βββ django_project/
β βββ manage.py
β βββ db.sqlite3 # SQLite database for local development
β βββ schema.yml # generated OpenAPI schema
β βββ accounts/
β β βββ models.py # CustomUser model
β β βββ tests.py
β β βββ views.py
β β βββ forms.py
β β βββ apps.py
β β βββ migrations/
β βββ posts/
β β βββ models.py # Post model
β β βββ serializers.py # REST serializers
β β βββ views.py # ViewSets and permission handling
β β βββ urls.py # Router-based API routes
β β βββ permissions.py # Custom permissions
β β βββ tests.py # API/model tests
β β βββ apps.py
β β βββ migrations/
β βββ django_project/
β βββ settings.py # Django configuration
β βββ urls.py # Root routing and docs endpoints
β βββ wsgi.py
β βββ asgi.py
- Python 3.11+
- Django 6.0.5
- Django REST Framework 3.17.1
dj-rest-authfor authentication endpointsdjango-allauthfor auth integrationsdrf-spectacularfor schema/documentationdjango-cors-headersfor CORS support- SQLite for development (
db.sqlite3)
git clone https://github.com/Nirajjj11/blog-app-rest-API-Django.git
cd "blog API by book"python -m venv .venv
.\.venv\Scripts\activateIf you are using Git Bash or Linux/macOS:
python -m venv .venv
source .venv/bin/activatepip install -r requirements.txtcd django_projectpython manage.py migratepython manage.py createsuperuserpython manage.py runserverThe API will be available at:
http://127.0.0.1:8000/api/v1/
The project uses a router, so the endpoints are grouped under /api/v1/.
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/api/v1/ |
List all posts |
POST |
/api/v1/ |
Create a post |
GET |
/api/v1/{id}/ |
Retrieve a single post |
PUT |
/api/v1/{id}/ |
Update a post |
PATCH |
/api/v1/{id}/ |
Partially update a post |
DELETE |
/api/v1/{id}/ |
Delete a post |
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/api/v1/users/ |
List users |
POST |
/api/v1/users/ |
Create a user |
GET |
/api/v1/users/{id}/ |
Retrieve a user |
PUT |
/api/v1/users/{id}/ |
Update a user |
PATCH |
/api/v1/users/{id}/ |
Partial update a user |
DELETE |
/api/v1/users/{id}/ |
Delete a user |
| Endpoint | Purpose |
|---|---|
/api/v1/dj-rest-auth/login/ |
Login and receive auth token |
/api/v1/dj-rest-auth/logout/ |
Logout and invalidate session/token |
/api/v1/dj-rest-auth/registration/ |
Register a new account |
/api/v1/dj-rest-auth/password/reset/ |
Password reset flow |
/api/v1/dj-rest-auth/password/change/ |
Password change flow |
/api/schema/ |
OpenAPI schema |
/api/schema/swagger-ui/ |
Swagger UI |
/api/schema/redoc/ |
Redoc UI |
curl -X POST http://127.0.0.1:8000/api/v1/dj-rest-auth/login/ \
-H "Content-Type: application/json" \
-d '{"username":"demo", "password":"demo123"}'curl -X POST http://127.0.0.1:8000/api/v1/ \
-H "Authorization: Token YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"New post title", "body":"This is the post content."}'Note: the author field is assigned automatically from the authenticated user. -H "Content-Type: application/json"
-d '{"title":"My first post","body":"Hello from the API"}'
### List posts
```bash
curl -H "Authorization: Token YOUR_TOKEN" http://127.0.0.1:8000/api/v1/
The current regression coverage checks the blog post model and its author relationship.
python manage.py testVerified locally with:
..\.venv\Scripts\python.exe manage.py test posts.tests --verbosity 2Result:
Ran 1 testOK
The API schema is generated using drf_spectacular and stored in schema.yml.
To regenerate the schema:
python manage.py spectacular --file schema.ymlThis project is simple, but there are a few important concepts to understand:
-
Custom user model setup
AUTH_USER_MODEL = "accounts.CustomUser"must be defined before migrations.- changing the user model after data exists is a migration-heavy operation.
-
Authentication design
- the project mixes DRF authentication classes (session + token) and external auth packages.
- in production, choose a single auth strategy that matches your frontend and security needs.
-
Database choice
- SQLite is fine for local development and demos.
- production should move to PostgreSQL (or another managed database) for reliability, concurrency, and backup support.
-
Secrets and environment variables
SECRET_KEY, database credentials, and service URLs should never be hardcoded in production.- use
.envfiles, environment variables, or a secret manager.
-
Debug and host configuration
DEBUG=Trueand emptyALLOWED_HOSTSare development-only settings.- production needs
DEBUG=False, a restrictedALLOWED_HOSTS, and secure headers.
-
Static/media files
- use a dedicated static/media storage backend in production (CDN, S3, Azure Blob, etc.).
-
Email backend
console.EmailBackendis useful for development only.- production should use SMTP or a transactional email service.
-
CORS and trusted origins
CORS_ORIGIN_WHITELISTandCSRF_TRUSTED_ORIGINSare development-oriented settings.- production should restrict allowed origins carefully.
-
Monitoring and logging
- add structured logging, request monitoring, and error tracking as traffic grows.
For production-grade deployment, consider:
- moving from SQLite to PostgreSQL
- using environment variables for configuration
- enabling HTTPS and secure cookies
- adding rate limiting and throttling
- introducing serializers and validation for stricter input control
- adding full test coverage for views, permissions, and auth flows
- adding pagination and filtering for large datasets
- adding API versioning and better error handling
This repository demonstrates how to build a Django REST API from scratch with:
- custom user models
- relational database models
- REST serializers and viewsets
- permission-based authorization
- auth endpoints
- schema documentation
- local development and production deployment considerations
If you want, this project can be extended into a full production API with PostgreSQL, Docker, JWT auth, image uploads, pagination, and CI/CD.