A simple full-stack blog application.
- Backend: Django + Django REST Framework
- Frontend: plain HTML, CSS, and vanilla JavaScript
- Auth: session-based login with CSRF protection
- Database: SQLite
This README is written to be easy for both humans and LLMs to parse. It explains the folder structure, how the app is supposed to work, how to run it, and the main API endpoints.
The app lets a user:
- register an account
- log in and log out
- view blog posts
- create a new post when authenticated
- view a single post
- add and delete comments
The frontend is a static site that talks to the Django API with fetch.
blog-project/
├── backend/
│ ├── manage.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ ├── blog/
│ │ ├── models.py
│ │ ├── serializers.py
│ │ ├── urls.py
│ │ └── views.py
│ └── users/
│ ├── urls.py
│ └── views.py
├── frontend/
│ ├── index.html
│ ├── login.html
│ ├── register.html
│ ├── create-post.html
│ ├── post.html
│ ├── css/
│ │ └── style.css
│ └── js/
│ ├── api.js
│ ├── auth.js
│ ├── index.js
│ └── post.js
└── README.md
Authentication is session-based, not token-based.
That means:
- the browser must send cookies with requests
- unsafe requests like POST need a CSRF token
- frontend requests should use
credentials: 'include'
frontend/index.htmlis the home pagefrontend/login.htmlhandles loginfrontend/register.htmlhandles registrationfrontend/create-post.htmlis the correct create-post pagefrontend/creat-post.htmlis a legacy typo page that redirects to the correct pagefrontend/post.htmlshows one post and its comments
backend/usershandles registration, login, logout, and current user lookupbackend/bloghandles posts and comments
From the backend/ folder:
./venv/bin/python manage.py runserverIf the database has just been created or reset, run migrations first:
./venv/bin/python manage.py makemigrations
./venv/bin/python manage.py migrateIf your virtual environment path is different, use the Python environment that belongs to this project.
Open the frontend/ folder with a local web server.
Recommended options:
- VS Code Live Server
- any local static server on
http://localhost:5500
Do not open the frontend with file:// if you want auth and CSRF-protected requests to work reliably.
POST /api/users/register/POST /api/users/login/POST /api/users/logout/GET /api/users/me/
GET /api/blog/posts/GET /api/blog/posts/<id>/POST /api/blog/posts/create/PUT /api/blog/posts/<id>/update/DELETE /api/blog/posts/<id>/delete/POST /api/blog/posts/<id>/comments/add/DELETE /api/blog/comments/<id>/delete/
A blog post stores:
- title
- content
- author
- created_at
- updated_at
- optional image
A comment stores:
- post
- author
- content
- created_at
- The user opens
frontend/create-post.html - The page sends a POST request to
/api/blog/posts/create/ - The request includes cookies and a CSRF token
- The backend saves the post with the authenticated user as the author
- The API returns the created post as JSON
- The user submits the login form
- The frontend calls
/api/users/login/ - Django creates a session cookie
- Later requests reuse that session cookie
GET /api/users/me/returns the current user when logged in
These are the most likely reasons something breaks:
- the backend server is not running
- migrations were not applied, so tables do not exist
- the frontend is opened with
file://instead of a local server - cookies are not being sent with
fetch - the CSRF token header is missing on POST, PUT, or DELETE requests
- the request is sent to the wrong port or origin
- Keep the frontend API calls in
frontend/js/api.js - Keep auth-related logic in
frontend/js/auth.js - Keep post list rendering in
frontend/js/index.js - Keep single-post and comment logic in
frontend/js/post.js - Keep API response shapes stable unless the frontend is updated too
- If you reset the database, re-run migrations before testing post creation
The important mental model is:
- this is a Django API plus static frontend
- login is session-based, not JWT-based
- CSRF matters for unsafe requests
- the create-post endpoint requires the
blog_posttable to exist - the frontend is intentionally simple and uses static HTML pages plus JavaScript modules
A good first debugging sequence is:
- confirm the backend is running
- confirm migrations are applied
- confirm login works and a session cookie exists
- confirm the request sends
X-CSRFToken - confirm the browser is using
credentials: 'include' - inspect backend traceback if the response is still 500
No license has been specified yet.