paws-rescue-donations
Paws Rescue Donations
An animal rescue takes in donations, and somebody has to record who gave what, and for which pet. Most small rescues use a shared spreadsheet where anyone with the link can change anything. This private website replaces it: staff sign in, log each donation against a pet, filter the records, see running totals and the top five pets, and export whatever they have filtered.
Overview
A Django web app for tracking donations at a pet rescue, built for the Khidmat community-service program at Habib University. Staff log in, record donations against individual pets, filter and export the records, and see running totals on a dashboard.
There is no public-facing side; the whole app sits behind an admin login. It replaces the spreadsheet small rescues usually use, which lacks access control and consistent fields, with a single database and a login, while staying simple enough to run on a free hosting tier.
Key features
- Email and password login with a custom user model (no usernames, no public signup).
- Donation CRUD with donor contact info, pet name, amount, currency, payment method, reference number, and notes.
- Filtering by name, date range, payment method, currency, and amount range, with sorting and pagination at 20 rows per page.
- Dashboard analytics: an all-time total, a filtered total, and the top 5 pets within the current filters, with CSV export of the filtered set.
- Admin user management from the web UI, with a management command to bootstrap the first admin from environment variables.
Results
Eleven tests cover auth redirects, admin creation and self-deletion protection, donation CRUD, filtering, amount validation, and the CSV export.
Tech stack
A challenge worth noting
Production security settings broke the whole test suite: SECURE_SSL_REDIRECT turned every test-client request into a 301 to https and Whitenoise manifest storage raised errors because tests never run collectstatic. The fix gates the security block on an explicit TESTING flag, since manage.py test does not set DEBUG=True.