products#
Core content platform powering blog posts, travel itineraries, categories, favourites, and user preferences. Supports multi-language translation and tier-based access control.
Models#
Model |
Description |
|---|---|
|
Content category with image, ordering, homepage toggle |
|
Markdown articles — neighbourhood guides, travel tips, analyses |
|
User travel preference data (JSON blob) |
|
User accommodation preference choice |
|
Travel mode option (walking, driving, cycling) |
|
Multi-day itinerary with PDF export and Google Maps link |
|
User’s saved blog post or itinerary bookmark |
URL Routes#
Key routes (the full products URL set is extensive):
Path |
View |
Description |
|---|---|---|
|
blog listing |
Paginated blog post index |
|
blog detail |
Single blog post with comments |
|
itinerary listing |
Browse itineraries |
|
itinerary detail |
Single itinerary with map |
|
search |
Full-text search across posts and itineraries |
Management Commands#
Command |
Description |
|---|---|
|
One-off data cleanup for duplicate schema records |
Access Control#
Blog posts and itineraries use a three-level access field:
Level |
Meaning |
|---|---|
|
Publicly visible |
|
Requires any active subscription tier |
|
Requires the premium subscription tier |
Key Design Decisions#
MarkdownX is used for the blog post body, providing a rich editor in the admin.
TaggableManager (django-taggit) enables flexible tagging for filtering and search.
Favourites use a generic FK pattern — a
Favoritecan reference either aBlogPostor anItinerary(both nullable FKs, one must be set).Series support:
series_number/series_totalfields let posts form ordered series.