A Django-based event management system for Fort Kent Outdoor Center, providing both a REST API for calendar integrations and a web-based management interface for staff.
- RESTful API for events, categories, and sessions
- Web-based admin dashboard with HTMX interactivity
- Multi-session event support (recurring classes, multi-day events)
- Event publication control (draft/published)
- PDF flyer attachments for events
- Calendar-optimized event feeds
- AWS S3/CloudFront integration for production storage
- Framework: Django 6.0
- API: Django REST Framework
- Database: SQLite (development) / PostgreSQL (production)
- Storage: Local filesystem or AWS S3 with CloudFront CDN
- Frontend: Tailwind CSS with HTMX for interactivity
- Python 3.10+
- pip
-
Clone the repository:
git clone https://github.com/your-org/api_fortkentoc_org.git cd api_fortkentoc_org -
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # Linux/macOS # or venv\Scripts\activate # Windows
-
Install dependencies:
pip install -r requirements.txt
-
Set up environment variables:
cp .env.example .env # Edit .env with your settings -
Run migrations:
python manage.py migrate
-
(Optional) Seed the database with test data:
python manage.py seed_db
-
Start the development server:
python manage.py runserver
The API will be available at http://localhost:8000/api/ and the management interface at http://localhost:8000/management/.
api_fortkentoc_org/
├── fkoc_backend/ # Django project configuration
│ ├── settings.py # Settings (DB, apps, REST config)
│ ├── urls.py # Root URL router
│ ├── storage_backends.py # AWS S3/CloudFront storage
│ └── wsgi.py
├── events/ # REST API app
│ ├── models.py # EventCategory, Event, EventSession
│ ├── views.py # DRF ViewSets
│ ├── serializers.py # API serializers
│ ├── filters.py # Query filters
│ ├── factories.py # Test factories
│ └── management/commands/
│ └── seed_db.py # Database seeding
├── management/ # Web UI app
│ ├── views.py # Dashboard & CRUD views
│ ├── forms.py # Django forms
│ ├── mixins.py # HTMX mixins
│ └── templates/ # HTML templates
├── integrations/ # External service integrations
├── media/ # User uploads (development)
├── requirements.txt
└── .env.example
Groups events by type (e.g., "Ski Lessons", "Races").
| Field | Type | Description |
|---|---|---|
| name | CharField | Category name (unique) |
| slug | SlugField | URL-friendly identifier (auto-generated) |
| sort_order | Integer | Display ordering |
Represents an event with one or more sessions.
| Field | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| title | CharField | Event title |
| description | TextField | Event description |
| category | ForeignKey | Link to EventCategory |
| flyer_pdf | FileField | Optional PDF flyer |
| is_published | Boolean | Publication status |
| created_at | DateTime | Creation timestamp |
| updated_at | DateTime | Last update timestamp |
Individual date/time occurrence of an event.
| Field | Type | Description |
|---|---|---|
| event | ForeignKey | Link to Event |
| date | DateField | Session date |
| start_time | TimeField | Start time |
| end_time | TimeField | End time (optional) |
Base URL: /api/
| Method | Endpoint | Description |
|---|---|---|
| GET | /categories/ |
List all categories |
| GET | /categories/{slug}/ |
Get category by slug |
| Method | Endpoint | Description |
|---|---|---|
| GET | /events/ |
List published events |
| POST | /events/ |
Create new event |
| GET | /events/{id}/ |
Get event details |
| PUT | /events/{id}/ |
Update event |
| PATCH | /events/{id}/ |
Partial update |
| DELETE | /events/{id}/ |
Delete event |
| GET | /events/calendar/ |
Calendar-optimized session list |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| start | date | Filter sessions starting on or after this date |
| end | date | Filter sessions ending on or before this date |
| category | string | Filter by category slug |
| include_past | boolean | Include past events (default: false) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /sessions/ |
List sessions |
| POST | /sessions/ |
Create session |
| GET | /sessions/{id}/ |
Get session details |
| PUT | /sessions/{id}/ |
Update session |
| DELETE | /sessions/{id}/ |
Delete session |
curl -X POST http://localhost:8000/api/events/ \
-H "Content-Type: application/json" \
-d '{
"title": "Beginner Ski Class",
"description": "Learn the basics of skiing",
"category_id": "ski-lessons",
"is_published": true,
"sessions": [
{
"date": "2024-01-20",
"start_time": "10:00:00",
"end_time": "12:00:00"
},
{
"date": "2024-01-27",
"start_time": "10:00:00",
"end_time": "12:00:00"
}
]
}'curl "http://localhost:8000/api/events/calendar/?start=2024-01-01&end=2024-03-31"The web-based management interface is available at /management/ and requires authentication.
| Path | Description |
|---|---|
/management/ |
Dashboard with event list |
/management/events/{id}/ |
Event detail page |
/management/categories/ |
Category management |
/accounts/login/ |
Login page |
/accounts/logout/ |
Logout |
When using seed_db, a test user is created:
- Username:
testuser - Password:
testpass123
Copy .env.example to .env and configure:
# Django Core
SECRET_KEY=your-secret-key
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
# Database (production)
DB_DB=fkoc_db
DB_USER=fkoc_user
DB_PASSWORD=your-password
DB_HOST=localhost
# AWS S3/CloudFront (optional)
USE_S3=False
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_STORAGE_BUCKET_NAME=your-bucket
AWS_S3_REGION_NAME=us-east-1
AWS_CLOUDFRONT_DOMAIN=d123456.cloudfront.net- Development: SQLite (automatic, no configuration needed)
- Production: PostgreSQL (set
DEBUG=Falseand configureDB_*variables)
- Development: Local filesystem (
media/directory) - Production: Set
USE_S3=Trueand configure AWS credentials
Populate the database with test data:
# Create test data
python manage.py seed_db
# Clear existing data and reseed
python manage.py seed_db --clear
# Specify number of events
python manage.py seed_db --events 25Creates:
- 7 event categories
- 15 events (default) with sessions
- Test user account
Run the test suite:
# All tests
python manage.py test
# Specific app
python manage.py test events
python manage.py test management
# Specific test file
python manage.py test events.tests.test_apiThe project uses Factory Boy for test data generation. Available factories in events/factories.py:
UserFactoryEventCategoryFactoryEventFactoryEventSessionFactoryFutureEventSessionFactoryPastEventSessionFactoryEventWithSessionsFactory
- Set
DEBUG=False - Configure PostgreSQL database
- Set a strong
SECRET_KEY - Configure
ALLOWED_HOSTS - Enable S3 storage (
USE_S3=True) - Run
python manage.py collectstatic - Set up HTTPS
For production with S3:
USE_S3=True python manage.py collectstatic --noinputThis uploads static files to your S3 bucket under the static/ prefix.
CORS is configured in settings.py:
- Production: Only
https://www.fortkentoc.orgis allowed - Development: All origins allowed when
DEBUG=True
To add additional origins, modify CORS_ALLOWED_ORIGINS in settings.
[Add your license here]