# Zoneco ORG Backend API A Django REST Framework backend for Zoneco ORG with PostgreSQL database. --- ## Test Status ``` Ran 24 tests in ~12s — OK (0 failures) ``` | Group | Tests | Status | |-------|-------|--------| | Contact Us | 6 | ✅ All pass | | Compositions | 11 | ✅ All pass | | Campaigns | 7 | ✅ All pass | Run tests at any time: ```bash cd backend python manage.py test api -v 2 ``` --- ## Features - **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 ```bash pip install -r requirements.txt ``` ### 2. Create PostgreSQL database ```sql CREATE DATABASE "Zoneco_ORG"; ``` ### 3. Apply migrations ```bash python manage.py migrate ``` ### 4. Run development server ```bash python manage.py runserver ``` API available at `{{base_url}}/api/` --- ## Admin Credentials | Field | Value | |-------|-------| | URL | `{{base_url}}/admin/` | | Username | `Zoneco_@1405` | | Password | `Fun_@_zone2026` | --- ## 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 — Basic Auth required | --- ### 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 |