A small Django app for managing contacts, contact methods (email/phone/social), and a minimal event scheduler attached to contacts. It provides a single-page-ish UI with a contact list and a detail pane that includes contact methods and per-contact events/calendar views.
This repository contains the backend (Django) and a small client-side UI written in vanilla JavaScript and CSS.
- Create, read, update and delete contacts
- Add/remove contact methods (email, phone, social)
- Minimal per-contact event scheduler (create/update/delete events)
- Calendar month grid view and list view of events
- Client-side validation for contact methods (basic dedupe & email format checks)
- Centralized AJAX helper that attaches CSRF token from page meta () and surfaces 403-friendly banners
- CLI smoke test (
tools/smoke.sh) that exercises create/update/delete flows and reports results
- Python 3.x
- Django (project entry:
manage.py, app modules:contact/,contact_method/,contacts_crud/) - SQLite included for local development (db.sqlite3 in repo) — switch to Postgres for production
- Frontend: vanilla JS (extracted to
static/js/home.js) and CSS instatic/css/home.css
manage.py— Django CLIcontacts_crud/— core Django settings and URL configcontact/— contact model, templates, and viewscontact_method/— contact method model and APIsstatic/— static assets (js, css, images)static/js/home.js— main client script (handles fetchJson, UI wiring, calendar views)static/css/home.css— styles
templates/— top-level templates (home.html)tools/smoke.sh— simple CLI smoke tester that extracts CSRF meta and exercises APIs
-
CSRF: client JS expects a
<meta name="csrf-token" content="{{ csrf_token }}">tag in the rendered page head. The smallfetchJson()helper reads this meta and setsX-CSRFTokenfor non-GET requests. This is intentional (explicit meta source) and works with Django'scsrf_tokentemplate tag whenCsrfViewMiddlewareis enabled. -
Static files: the UI was refactored to move inline JS into
static/js/home.jsand the template now includes it via{% static 'js/home.js' %}. Make surecollectstaticand your static-file serving (WhiteNoise, nginx, CDN) are configured in production. -
Client validation: some UX validation exists (email regex, duplicate contact methods, event overlap checks). These are client-side conveniences only — server-side validation and DB constraints are required for authoritative enforcement under concurrency.
-
Events overlap: the UI performs an overlap check for events per contact as a UX guard.
There is a small helper script tools/smoke.sh that:
- fetches the homepage to extract the CSRF meta token
- runs a create -> update -> create event -> update event -> delete event -> delete contact lifecycle
- stores temporary outputs for debugging
Usage (local dev):
chmod +x tools/smoke.sh
./tools/smoke.shThe project exposes JSON endpoints for contacts and events. Examples (relative to site root):
GET /contacts/api/— list contacts (UI uses template-rendered list, check views)POST /contacts/api/create/— create contact (expects JSON payload)GET /contacts/api/<pk>/— fetch contact detail including methods and eventsPOST /contacts/api/<pk>/update/— update contactDELETE /contacts/api/<pk>/delete/— delete contactPOST /contacts/api/<pk>/events/create/— create event for contactPOST /contacts/event/<event_id>/update/— update eventDELETE /contacts/event/<event_id>/delete/— delete event
(See the app views.py files for exact request/response shapes.)
static/js/home.js— main front-end logic (fetchJson helper, renderers, DOM wiring)static/css/home.css— styles (recent tweaks: event header alignment and image-button hover darken)templates/home.html— page layout and meta tag for CSRF tokentools/smoke.sh— CLI smoke testcontact/,contact_method/— models, views and admin