Design, save, and send beautiful occasion cards — a Moonpig-style Django plugin
Project description
Piggyback 🐷
Design, save, and send beautiful occasion cards in Django.
Piggyback is a Moonpig-style Django plugin that lets your users design personalised greeting cards, save them to a library, and send by email or post — with a full REST API, card editor, address book, reminders, gift add-ons, and checkout flow.
Landing Page · Documentation · API Reference
Features
| Feature | Description |
|---|---|
| Card Designer | Fabric.js editor with Alpine.js UI + HTMX send flow |
| Card Shop | Browse templates by occasion (birthday, wedding, sympathy…) and style |
| Card Library | Auto-synced drafts, saved designs, sent cards, favourites |
| E-Cards | Instant email delivery with branded view page |
| Posted Cards | Pluggable postal fulfilment backend |
| Address Book | Recipients with email, postal address, birthdays |
| Reminders | Cron-ready birthday/anniversary email reminders |
| Gift Add-ons | Chocolates, candles, prosecco, gift wrap |
| Checkout | Cart, promo codes, payment hooks (Stripe-ready) |
| REST API | Full DRF API for headless/mobile integrations |
| Admin | Django admin for all models |
Docker
docker compose up --build
Open http://localhost:8000 — demo login demo / demo12345. See Docker docs.
Quick install
pip install pypiggyback
# settings.py
INSTALLED_APPS = [
# ...
"rest_framework",
"django_filters",
"piggyback",
]
# urls.py
urlpatterns = [
path("", include("piggyback.urls")),
]
python manage.py migrate
python manage.py load_sample_data
python manage.py runserver
Visit http://localhost:8000 — browse cards, open the editor, sign in via /admin/login/ to save and send.
Run the Example Project
git clone https://github.com/kurtisrogers/piggyback.git
cd piggyback
pip install -e ".[dev]"
cd example
python manage.py migrate
python manage.py load_sample_data
python manage.py createsuperuser
python manage.py runserver
API Example
# Browse templates (no auth)
curl http://localhost:8000/api/templates/
# Personalise a template (authenticated)
curl -X POST http://localhost:8000/api/templates/birthday-general-classic/personalize/ \
-b "sessionid=YOUR_SESSION"
# Add to cart and checkout
curl -X POST http://localhost:8000/api/orders/add_to_cart/ \
-H "Content-Type: application/json" \
-d '{"card_id": 1, "recipient_id": 1, "delivery_method": "ecard"}'
Configuration
PIGGYBACK_PUBLIC_URL = "https://cards.yoursite.com"
PIGGYBACK_ECARD_PRICE = 299 # pence (£2.99)
PIGGYBACK_POSTED_CARD_PRICE = 399
PIGGYBACK_REMINDER_DAYS_BEFORE = [7, 3, 1]
# Reuse existing User/profile details (no duplicate data entry)
PIGGYBACK_USER_PROFILE_RELATION = "profile"
PIGGYBACK_PROFILE_FIELD_MAP = {"phone": "phone_number", "address_line_1": "line1", ...}
See the configuration docs and system user details guide.
Project Structure
src/piggyback/ # Django app
├── models/ # Catalog, cards, orders, recipients, reminders
├── api/ # DRF viewsets and serializers
├── views/ # Web UI views
├── services/ # Delivery, checkout, rendering, reminders
├── templates/ # HTML templates + email templates
├── static/ # CSS + Fabric.js editor
└── management/ # load_sample_data, send_reminders
example/ # Demo Django project
docs/ # MkDocs documentation
landing/ # GitHub Pages landing page
tests/ # pytest suite
Development
pip install -e ".[dev]"
pre-commit install
playwright install chromium
pytest # unit + BDD (22 tests)
pre-commit run --all-files
mkdocs serve -f docs/mkdocs.yml
- Fixtures:
python manage.py load_sample_data --fixture - Unit tests:
pytest tests/ --ignore=tests/bdd - BDD E2E:
pytest tests/bdd(Playwright + Gherkin) - Branch protection: see
docs/development/branch-protection.md(requires repo admin)
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pypiggyback-0.1.0.tar.gz.
File metadata
- Download URL: pypiggyback-0.1.0.tar.gz
- Upload date:
- Size: 41.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3329c711ea0d89679567fd55f2edc9a28e89df4cf7c3203cb18a654717ffd33
|
|
| MD5 |
5ba0f488e02652dcfbea7e6e1e365eab
|
|
| BLAKE2b-256 |
f4dee2e4f869a1dfbf4e935a9c9a7b99ac681b4766e93ec5ce021ed7034645c7
|
Provenance
The following attestation bundles were made for pypiggyback-0.1.0.tar.gz:
Publisher:
workflow.yml on kurtisrogers/piggyback
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pypiggyback-0.1.0.tar.gz -
Subject digest:
b3329c711ea0d89679567fd55f2edc9a28e89df4cf7c3203cb18a654717ffd33 - Sigstore transparency entry: 2193993627
- Sigstore integration time:
-
Permalink:
kurtisrogers/piggyback@ee9f10af39effcf8d8ce8df7d9cf1c28155c3bf7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kurtisrogers
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@ee9f10af39effcf8d8ce8df7d9cf1c28155c3bf7 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pypiggyback-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pypiggyback-0.1.0-py3-none-any.whl
- Upload date:
- Size: 65.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ed7413e77ba5c215c7ce5ad652b7226c5160097355ce085aec5a6fcde47afe0
|
|
| MD5 |
8207c9716e9a7ba91053f41d47ee3970
|
|
| BLAKE2b-256 |
62c0733e6b0a2ada31729da1e88609fc0c6e398a697c698ccdb98f4e8fc1bc8a
|
Provenance
The following attestation bundles were made for pypiggyback-0.1.0-py3-none-any.whl:
Publisher:
workflow.yml on kurtisrogers/piggyback
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pypiggyback-0.1.0-py3-none-any.whl -
Subject digest:
4ed7413e77ba5c215c7ce5ad652b7226c5160097355ce085aec5a6fcde47afe0 - Sigstore transparency entry: 2193993637
- Sigstore integration time:
-
Permalink:
kurtisrogers/piggyback@ee9f10af39effcf8d8ce8df7d9cf1c28155c3bf7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kurtisrogers
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@ee9f10af39effcf8d8ce8df7d9cf1c28155c3bf7 -
Trigger Event:
workflow_dispatch
-
Statement type: