Skip to main content

Django Hotels API

PyPI version Python versions License Unit Tests

This is a Django REST API for managing and retrieving hotels, room types, availability, and bookings.

This service is a sibling of django-trips, and is a core component of the DestinationPak project — a platform designed to make exploring and booking adventures across Pakistan easier and more accessible.

Installation

Simply do:

pip install django-hotels

Usage

Add the app (and django_filters, used by the catalog/availability filtering below) into your installed apps in your project's settings file.

INSTALLED_APPS = [
    ...
    'django_filters',
    'django_hotels',
]

Migrate

python manage.py migrate

Add the following to your root urls.py or to your desired file location.

urlpatterns = [
    ...
    path('hotels/', include('django_hotels.urls')),
]

This mounts the whole app under your own chosen namespace (hotels/ above - replace with whatever prefix you like) with the lib's own v1/ version underneath it, e.g. hotels/v1/hotels/. The app versions itself independently of your project's own API version.

Domain model

HotelOwner (the business/brand)
  └── Hotel (one bookable property)
        ├── HotelImage
        └── HotelRoomType (a room category/tier)
              └── HotelAvailability (a dated, priced, bookable instance)
                    └── HotelBooking (a guest or logged-in traveller's booking)

HotelOwner/Hotel deliberately carry no login/auth/permission fields — this package is tenancy-oblivious, the same way django-trips is. A consuming project owns the membership layer (who may manage which HotelOwner), not this library.

Public API

Read-only and unauthenticated (AllowAny) unless noted:

  • hotels/ - the published catalog. Filterable via query params: ?city=, ?status=, ?owner=<id>.
  • hotels/<slug>/ - one hotel's detail, including its room types.
  • owners/ - active, verified HotelOwners.
  • availabilities/ - date-range availability search across active hotels' room types. Filterable via ?hotel=<slug>, ?room_type=<id>, ?date_from=, ?date_to= (any combination; omitting all three returns every upcoming bookable date).
  • bookings/create/ - guest booking (no auth required).
  • bookings/lookup/?number=&email= (or &otp= instead of email) - guest "find my booking".
  • bookings/<number>/ - authenticated traveller's own booking (retrieve/update).
  • schema/, schema/swagger-ui/, schema/redoc/ - this app's own OpenAPI schema, scoped to just these endpoints regardless of what else your project mounts.

Custom Location model

django_hotels.Location (a plain name/slug/lat/lng model, no region/parent hierarchy) is swappable, the same way Django's own AUTH_USER_MODEL is - if your project already has its own location/city model, you don't have to duplicate location data into a second table just to install this app.

Two settings, both optional and both defaulting to this package's own bundled model:

  • DJANGO_HOTELS_LOCATION_MODEL - an "app_label.ModelName" string naming which model actually satisfies Hotel.location, e.g. DJANGO_HOTELS_LOCATION_MODEL = "myapp.City". Your model doesn't need to share Location's field names.
  • DJANGO_HOTELS_LOCATION_ADAPTER - a dotted path to a django_hotels.location_adapter .LocationAdapter subclass telling this app how to read your model's fields as if they were Location's (get_name, get_slug, get_lat, get_lng). Every place this app reads a location goes through django_hotels.location_adapter.get_location_adapter(), never by field name directly, so your adapter is the only place that needs to know your model's real shape.

Set both before your project's first migrate. Like AUTH_USER_MODEL, this is a swappable-model setting - Django resolves it once when the app loads, and a swap made after Location's own table has already been created doesn't retroactively move existing data.

Hotel.city (the original free-text field) stays in place alongside the new Hotel.location FK for now - a data migration best-effort backfills location from each existing city string (matching or creating a Location by name), leaving it null wherever city is blank. city itself is only dropped once every consumer has finished backfilling against its own chosen Location model.

For a worked example of a real swap: the DestinationPakistan platform (this package's own primary consumer, a private project) points this setting at its own public.City model via a HotelsRentalsCityLocationAdapter in its djangoapps/public/adapters.py - the same shape sketched above, just concretely filled in.

Local development

All commands assume Docker (make dev.up, make update_db, make test) — see the Makefile for the full command list (make help).

Generate demo data

./manage.py generate_hotels --batch_size=10

Release files for django-hotels 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-hotels 0.2.0
File Size Uploaded
django_hotels-0.2.0.tar.gz 18.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-hotels 0.2.0
File Interpreter ABI Platform
django_hotels-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 39.6 kB

Release files / django_hotels-0.2.0.tar.gz

Download URL django_hotels-0.2.0.tar.gz
Size 18.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8fac39cc6bcbf8ebaa7fd7503aca7cfdacf98afc2b1e1717ac3a0fc23a4fcbdf
BLAKE2b-256 checksum
How to use checksums
9828fe5a1129f46543895e29799adf0fd29902f699962b6c571cb5bdf797fb5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release files / django_hotels-0.2.0-py3-none-any.whl

Download URL django_hotels-0.2.0-py3-none-any.whl
Size 21.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e3cb5acf701c205aaa2cc30c0b6b11923fdb0c679003a93e04e347aa2257eebf
BLAKE2b-256 checksum
How to use checksums
7ec6899595eb220e8970086a6a6c21386154fa4dae79411f132c8cbe4a343c27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.0

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page