Trips App
Overview
The idea of this project is to have one place (a database) to save info about my trips and flight searches. Then to build a Django app to display and interact with that info.
GitHub repo: trips.
A work in progress version of the app running here: Trips (creds: user: demo / pass: demo2022).
The project is centered on the Trips app and inside the Trips app the main model is Trip. There are, in all, ten models. The project itself has three apps: Trips (the main app), Base (a general purpose app), and Users (and app handling the users related properties).
The Trip App Models
The Trip model
This would be the main model of the project. The goal with this model is to have a table which captures most of the useful information related to a trip.
Practically, the attributes of this model can be grouped in three categories: general info about the trip, info about the outgoing leg of the trip, and info about the returning leg of the trip.
The attributes related to the details of the trip, the general info, are these:
name- not uniqueoriganddestfor the departing and, respectively, arriving point of the trip.travfor the number of travellerspriceandcurrencydate_foundandsource_found. These two fields are useful both for past trips and for saved search results.- a
notesattribute
The next two groups of attributes are related to the outgoing and returning parts of the trip:
out_dep_dateandout_dep_dayout_arr_dateandout_arr_dayout_stop_durationandout_durationout_priceandout_classout_first_flight,out_first_flight_dep_term, andout_first_flight_arr_termout_second_flight,out_second_flight_dep_term, andout_second_flight_arr_term
and for returning half of the trip:
ret_dep_dateandret_dep_dayret_arr_dateandret_arr_dayret_stop_durationandret_durationret_priceandret_classret_first_flight,ret_first_flight_dep_term, andret_first_flight_arr_termret_second_flight,ret_second_flight_dep_term, andret_second_flight_arr_term
This model tries to cover both, one-way trip and return trip.
The Flight Model
This model has nine attributes and it tries to represent what I needed to save for the flights I used or I found in my searches.
namedurationairlineairplanedepart_airportanddepart_timearrive_airportandarrive_time- a
notesfield
Initially, all of the attributes were CharField but later I found it useful to have separate tables for airplane, airline, airport and the related airport terminal as well as city for location.
The City, Airline, Airplane, Airport, and AirportTerminal Models
These are smaller models with just a few attributes.
The City model attributes: name (unique), country, prov_st, and notes.
The Airline model attributes: name (unique), country, and notes.
The Airplane model attributes: name (unique), and notes.
The Airport model attributes: name (unique), code, city, and notes.
The AirportTerminal model attributes: name (not unique), airport, and notes.
The Traveller and Seat models
The idea with these two models is to save in two different tables which family member was on a specific trip and which seat was on the flight. This looks interesting to save.
The Traveller model attribute: name (unique), and notes.
The Seat model attributes: seat_number, traveller, trip, flight, and notes.
Models Relationships and Dependencies
Relationships between models
City
Airline
Airplane
Airport - city ==> City - PROTECT
AirportTerminal - airport ==> Airport - PROTECT
Flight - airline ==> Airline - PROTECT
- airplane ==> Airplane - PROTECT
- depart_airport ==> Airport - PROTECT
- arrive_airport ==> Airport - PROTECT
TripSource
TripClass - airline ==> Airline - PROTECT
Trip - orig ==> City - PROTECT
- dest ==> City - PROTECT
- source_found ==> TripSource - PROTECT
- out_class ==> TripClass - SET_NULL
- out_first_flight ==> Flight - PROTECT
- out_first_flight_dep_term ==> AirportTerminal - SET_NULL
- out_first_flight_arr_term ==> AirportTerminal - SET_NULL
- out_second_flight ==> Flight - PROTECT
- out_second_flight_dep_term ==> AirportTerminal - SET_NULL
- out_second_flight_arr_term ==> AirportTerminal - SET_NULL
- ret_class ==> TripClass - SET_NULL
- ret_first_flight ==> Flight - PROTECT
- ret_first_flight_dep_term ==> AirportTerminal - SET_NULL
- ret_first_flight_arr_term ==> AirportTerminal - SET_NULL
- ret_second_flight ==> Flight - PROTECT
- ret_second_flight_dep_term ==> AirportTerminal - SET_NULL
- ret_second_flight_arr_term ==> AirportTerminal - SET_NULL
Traveller
Seat - traveller ==> Traveller - PROTECT
- trip ==> Trip - PROTECT
- flight ==> Flight - PROTECT
Dependencies:
City dependencies: Airport, Trip
Airline dependencies: Flight, TripClass
Airplane dependencies: Flight
Airport dependencies: AirportTerminal, Flight, Trip
AirportTerminal dependencies: none (Trip is SET_NULL)
Flight dependencies: Trip, Seat
TripSource dependencies: Trip
TripClass dependencies: none (Trip is SET_NULL)
Trip dependencies: Seat
Traveller dependencies: none
Seat dependencies: none
Base App
In this project base app doesn't have any models.
Views in Base App
The base app has several views which are subclassed by the views in the trips app, views for error pages, and a search view.
BaseItemsList View
This class is subclassing the generic ListView and is used to display items either as a list of links or as boxes.
For template it's using base_items_list_boxes.html as a generic way to display the items in
It is subclassed by the folowing view classes in the trips app:
- AirplaneList
- TripSourceList
- TripClassList
- TravellerList
BaseItemsTable View
This class is subclassing the generic View and is used to display the items in a table created with django_tables2.
For template it's using base_items_list_table.html.
It is subclassed by the following view classes in the trips app:
- CityTable
- AirlineTable
- AirportTable
- AirportTerminalTable
- FlightTable
- SeatTable
BaseItemsSearchResults View
This class is subclassing the generic View and is used to display the search results in tables.
For template it's using base_search_results.html.
It is subclassed by the following view classes in the trips app:
- CitySearchResults
- AirlineSearchResults
- AirplaneSearchResults
- AirportSearchResults
- AirportTerminalSearchResults
- FlightSearchResults
- TripSourceSearchResults
- TripClassSearchResults
- TripSearchResults
- TravellerSearchResults
- SeatSearchResults
BaseItemCreateWithPopup
This class is subclassing the generic CreateView. It is used to display a popup window (same like Django admin) to create a new item from within a form. It's used with forms for models which have ForeignKey relationships to other models.
It is subclassed by the following views in the trips app:
- CityCreate
- AirlineCreate
- AirplaneCreate
- AirportCreate
- AirportTerminalCreate
- FlightCreate
- TripSourceCreate
- TripClassCreate
- TravellerCreate
BaseItemEdit
This class is subclassing the generic UpdateView. It is used for editing an existing instance.
It is subclassed by the following views from trips app:
- CityEdit
- AirlineEdit
- AirplaneEdit
- AirportEdit
- AirportTerminalEdit
- FlightEdit
- TripSourceEdit
- TripClassEdit
- TripEdit
- TravellerEdit
- SeatEdit
Practically all the edit views from the trips app are using this class from the base app. This class adds to the get_context_data method the type of verbose name of the model and that is used later in the templates.
Error pages Views
custom_page_not_found_view- for 404 errorcustom_error_view- for 500 errorcustom_permission_denied_view- for 403 errorcustom_bad_request_view- for 400 error
They work together with the handler definition from the project urls.
handler404 = 'base.views.custom_page_not_found_view'
handler500 = 'base.views.custom_error_view'
handler403 = 'base.views.custom_permission_denied_view'
handler400 = 'base.views.custom_bad_request_view'
Search View
The role of this view is to display the results of site-wide searches in tables for each of the model instances for whcih there are results.
Other Components in Base App
Forms
One form defined here, the Search Form. Used in the search view.
Context Processors
One definition for a context processor - the one used to get the project version from settings.py and make it available to all the templates. It's result is used in the footer to display the version number.
Widgets
Four custom widgets are defined in the base app for this project
RelatedFieldWidgetSingle
It's subclassing the Select widget.
This is used in the forms with fields that have ForeignKey and it displays (like in Django Admin) a plus sign to create a new object.
SplitDurationWidget and MultiValueDurationField
Used in the filter form in the trips list view.