Files
site_backend/README.md
Shayan Azadi 50c9cf613f Add admin login API and remove hardcoded secrets
- Add token-based admin login/logout/me endpoints
- Bootstrap admin from ADMIN_USERNAME/ADMIN_PASSWORD in Docker entrypoint
- Read ALLOWED_HOSTS and CORS from env only (no hardcoded server IPs)
- Keep docs/Postman/tests free of real credentials
- Cover login and auth flows with 31 local API tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 17:29:47 +03:30

7.8 KiB

Zoneco ORG Backend API

A Django REST Framework backend for Zoneco ORG with PostgreSQL database.


Test Status

Ran 31 tests — OK (0 failures)
Group Tests Status
Admin Login 7 All pass
Contact Us 6 All pass
Compositions 11 All pass
Campaigns 7 All pass

Run tests at any time:

cd backend
python manage.py test api -v 2

Features

  • Admin Login API — Token-based login with username/password
  • Contact Us API — Contact form submissions with category filter
  • Composition API — Multi-image upload, main image flag, date-range filter
  • Campaign API — Campaigns with active / upcoming / ended filters
  • Admin Panel — Full Django admin at /admin/
  • Image Upload — JPEG, PNG, WebP, GIF, max 5 MB, stored in media/
  • CORS Enabled — Configured for frontend integration
  • Pagination — 20 items per page

Quick Start

1. Install dependencies

pip install -r requirements.txt

2. Create PostgreSQL database

CREATE DATABASE "Zoneco_ORG";

3. Apply migrations

python manage.py migrate

4. Run development server

python manage.py runserver

API available at {{base_url}}/api/


Admin Credentials

Set these in the server .env (never hardcode in code):

Env var Purpose
ADMIN_USERNAME Admin username for Docker bootstrap
ADMIN_PASSWORD Admin password for Docker bootstrap
Endpoint Path
Django Admin Panel {{base_url}}/admin/
API Login POST {{base_url}}/api/admin/login/

On Docker deploy, entrypoint.sh creates/updates the admin from ADMIN_USERNAME / ADMIN_PASSWORD.


Admin Login API

Login

POST {{base_url}}/api/admin/login/
Content-Type: application/json
{
  "username": "{{admin_username}}",
  "password": "{{admin_password}}"
}

Response:

{
  "token": "<token>",
  "user": {
    "id": 1,
    "username": "<admin_username>",
    "is_staff": true,
    "is_superuser": true
  }
}

Use the token on protected endpoints

Authorization: Token <your_token_here>

Current admin user

GET {{base_url}}/api/admin/me/
Authorization: Token <token>

Logout (deletes the token)

POST {{base_url}}/api/admin/logout/
Authorization: Token <token>

API Endpoints

Authentication

Action Access
GET (list, retrieve, custom filters) Public — no login required
POST (create) Public — no login required
PUT / PATCH / DELETE Admin only — Token required
Admin login / logout / me See Admin Login API above

Contact Us — /api/contact-us/

Method Endpoint Access Description
GET /api/contact-us/ Public List all submissions
POST /api/contact-us/ Public Submit a contact form
GET /api/contact-us/{id}/ Public Get one submission
GET /api/contact-us/by_category/?category=... Public Filter by category
PATCH /api/contact-us/{id}/ Admin Partial update
PUT /api/contact-us/{id}/ Admin Full update
DELETE /api/contact-us/{id}/ Admin Delete

Category choices: همکاری · فروش · پشتیبانی · درخواست مشاور · سایر

Fields:

Field Type Required
name string Yes
email_or_phone string Yes
description string Yes
category string Yes

Compositions — /api/compositions/

Each composition can have multiple images. One image can be flagged as the main image (is_main: true).

Method Endpoint Access Description
GET /api/compositions/ Public List all compositions
POST /api/compositions/ Public Create composition (with optional images)
GET /api/compositions/{id}/ Public Get one composition
GET /api/compositions/by-created-at/?from=...&to=... Public Filter by creation date range
POST /api/compositions/{id}/add-images/ Admin Add images to existing composition
POST /api/compositions/{id}/set-main-image/ Admin Set main image
DELETE /api/compositions/{id}/images/{image_id}/ Admin Delete a single image
PATCH /api/compositions/{id}/ Admin Partial update
PUT /api/compositions/{id}/ Admin Full update
DELETE /api/compositions/{id}/ Admin Delete composition

Fields:

Field Type Required Notes
name string Yes
description string Yes
uploaded_images file[] No One or more image files (multipart)
main_image_index integer No 0-based index of main image in uploaded_images. Defaults to 0.

Image constraints: JPEG, PNG, WebP, GIF — max 5 MB each — stored at media/compositions/

by-created-at query params:

Param Required Format
from At least one ISO 8601 e.g. 2026-06-01T00:00:00Z
to At least one ISO 8601 e.g. 2026-06-30T23:59:59Z

Campaigns — /api/campaigns/

Method Endpoint Access Description
GET /api/campaigns/ Public List all campaigns
POST /api/campaigns/ Public Create campaign
GET /api/campaigns/{id}/ Public Get one campaign
GET /api/campaigns/active/ Public Currently active campaigns
GET /api/campaigns/upcoming/ Public Not started yet
GET /api/campaigns/ended/ Public Already finished
PATCH /api/campaigns/{id}/ Admin Partial update
PUT /api/campaigns/{id}/ Admin Full update
DELETE /api/campaigns/{id}/ Admin Delete

Fields:

Field Type Required Notes
name string Yes
description string Yes
start_time datetime Yes ISO 8601
end_time datetime Yes Must be after start_time
image file No Campaign image (multipart)

Read-only computed fields: is_active, is_upcoming, is_ended


Models

ContactUs

Field Type
name CharField
email_or_phone CharField
description TextField
category CharField (choices)
created_at DateTimeField (auto)
updated_at DateTimeField (auto)

Composition

Field Type
name CharField
description TextField
image ImageField (legacy)
created_at DateTimeField (auto)
updated_at DateTimeField (auto)

CompositionImage

Field Type
composition ForeignKey → Composition
image ImageField
is_main BooleanField
created_at DateTimeField (auto)

DB constraint: only one is_main=True per composition.

Campaign

Field Type
name CharField
description TextField
start_time DateTimeField
end_time DateTimeField
image ImageField
created_at DateTimeField (auto)
updated_at DateTimeField (auto)

Media Files

Content Path
Composition images media/compositions/
Campaign images media/campaigns/

Postman Collection

Import backend/Zoneco_ORG_API.postman_collection.json into Postman.

Set the base_url collection variable to your server address.


Persian Documentation

Full Persian API documentation: backend/API_DOCS_FA.md


HTTP Status Codes

Code Meaning
200 OK
201 Created
204 Deleted (no body)
400 Invalid data
403 Forbidden (login required)
404 Not found