HTTP is the primary communication protocol between Pytigon's frontend and backend. Every user interaction — loading a table, submitting a form, clicking a button — flows through HTTP requests and responses, whether the client is a web browser, a wxPython desktop app, or a mobile device.
Every Pytigon view URL serves two purposes simultaneously:
HTML Page — When accessed normally (GET with Accept: text/html), the view returns a fully rendered HTML page with Bootstrap layout, navigation, and content.
API Endpoint — When accessed with ?format=json or Accept: application/json, the same URL returns structured JSON data — perfect for AJAX calls from the frontend JavaScript library.
This means you never need separate "page" and "API" URLs. One URL. Two representations. Zero duplication.
A typical HTTP interaction follows this pattern:
[Browser/Client]
│
│ GET /tables_demo/table/Album/list/
│ ├─ Cookies: sessionid=abc123
│ └─ Accept: text/html
│
▼
[Pytigon View]
│
│ 1. Authentication (Django session middleware)
│ 2. Permission check (view permissions)
│ 3. QuerySet building (model queryset + filters)
│ 4. Context preparation (template variables)
│ 5. Template rendering (.ihtml → .html → response)
│
▼
[Client receives HTML page]
│
│ AJAX: GET /tables_demo/table/Album/list/?format=json&offset=0&sort=name
│ (JavaScript table component requests data)
│
▼
[Pytigon View]
│
│ Same view, but:
│ ├─ Detects format=json
│ └─ Returns JSON array of table rows
│
▼
[Client renders table rows via JavaScript]
The frontend table component uses progressive loading:
Initial page load → HTML skeleton with empty table placeholder
→ JavaScript fires AJAX request for first page of data
→ Server returns JSON row data
→ JavaScript renders rows into the table
→ User scrolls → next page loaded via AJAX
This provides: - Fast initial page load (skeleton renders immediately) - Infinite scroll experience - Server-side sorting and filtering - Minimal data transfer (only the visible rows)
Forms follow two patterns:
POST /tables_demo/table/Album/1/edit/
Content-Type: application/x-www-form-urlencoded
name=New+Name&artist=New+Artist...
→ Server validates, saves, redirects to list view
POST /tables_demo/table/Album/1/edit/
Content-Type: application/json
X-Requested-With: XMLHttpRequest
{"name": "New Name", "artist": "New Artist"}
→ Server validates, saves
→ Returns JSON: {"success": true, "redirect": "/...", "errors": null}
The frontend JavaScript detects the X-Requested-With header in the response and handles it accordingly — showing validation errors inline or redirecting on success.
Custom actions (export, batch operations, workflow transitions) use POST requests to action URLs:
POST /tables_demo/table/Album/action/export_pdf/
Content-Type: application/json
{"selected_ids": [1, 2, 3], "format": "pdf"}
→ Server processes action
→ Returns JSON or triggers file download
HTTP error responses follow a consistent pattern:
{
"error": true,
"message": "Permission denied",
"code": 403,
"details": "You do not have permission to edit this record."
}
The frontend JavaScript intercepts these and displays appropriate user-facing messages — modal dialogs for blocking errors, toast notifications for informational errors.