Peer-to-peer rental marketplace: people list objects they own, other people rent them. Django REST API with JWT auth, part of a three-service system.
Most student marketplaces stop at "create listing, click rent, done". The hard part of renting physical objects is that the object has to physically travel to someone and come back, and either side can fail to do their part.
The API models that as an explicit state machine, with a separate endpoint for each transition and each side of it:
arrendar-objeto/ renter requests the object
confirmacion-entrega-cliente-envio/ owner marks it as sent
aceptar-entrega-cliente/ renter confirms receipt
enviar-propietario-devolucion/ renter marks it as returned
aceptacion-propietario-devolucion/ owner confirms it came back
cancelar-arrendamiento/ either side backs out
Both parties have to confirm each handover, so neither can unilaterally declare
the transaction complete. Availability, delivery date and return date live on
ServicioArrendamiento, separate from the object itself, so one object can carry
a history of rentals.
| Model | Purpose |
|---|---|
CustomUser |
Extends AbstractUser; national ID as unique key, with length validation |
ObjetoArrendamiento |
Listing: owner, category, price, availability, rating |
ServicioArrendamiento |
One rental: delivery date, return date, state |
| Repository | Role |
|---|---|
| RentHub_backend (this one) | Django REST API, JWT, object and rental lifecycle |
| RentHub_frontend | React + Vite client |
| RentHub_pago_microservicio | Node payment service, Stripe |
Payments are deliberately a separate service: card data never touches the Django app, which keeps the compliance surface small.
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
python manage.py migrate
python manage.py runserverBrowsable API docs at /docs/.
- No automated tests
- Ratings are a bare integer on the object, with no per-rental review
- The state machine lives across views rather than in one place, so an invalid transition is prevented by whichever view happens to check for it
- No dispute path: if the two parties disagree about whether an object came back, the API has nothing to say