Modèles plans et vues pour les aéroports
========================================
Pour vous habituer à l'utilisation de la base de données et la notion de clefs étrangères, ajoutez une table ``airport`` à votre base de données. Pour cela, modifiez le fichier ``schema.sql`` en ajoutant le code suivant sans supprimer le code que vous avez déjà mis.
.. container:: literal-block-wrapper docutils
:name: id2-create-street
.. container:: code-block-caption
``mobility/schema.sql``
.. code-block:: sql
DROP TABLE IF EXISTS airport;
CREATE TABLE airport(iata_code TEXT PRIMARY KEY,
name TEXT,
iso_country TEXT,
FOREIGN KEY (iso_country) REFERENCES country(iso_country)
);
INSERT INTO airport(iata_code,name, iso_country ) VALUES("ENF","Enontekio Airport", "FI");
Ce code ajoute une table ``airport`` à notre base de données et insère un aéroport. La table a trois colonnes : ``iata_code``, ``name`` et ``iso_country``. La colonne ``iata_code`` est une clef primaire, la colonne ``name`` est le nom de l'aéroport et la colonne ``iso_country`` est une clef étrangère qui fait référence à la colonne ``iso_country`` de la table ``country``. Dans la base de données qui vous sera fournie, la table ``airport`` comprendra deux colonnes supplémentaires donnant respectivement la longitude et la latitude de l'aéroport. Dans le cadre de cet exercice, nous allons prendre une version simplifiée de cette table.
La procédure qui va suivre est très similaire à celle que nous avons suivie pour la table ``country``. Créez un fichier que vous nommez ``airport.py`` dans le dossier ``models`` et ajoutez-y le code suivant. Ensuite, complétez le code ci-dessous :
.. container:: literal-block-wrapper docutils
:name: idairport
.. container:: code-block-caption
``mobility/models/airport.py``
.. code-block:: python
def get_airport_list():
# TODO
# Retourne la liste des aéroports, ainsi que le nom du pays correspondant
# trier par ordre alphabétique sur base du nom du pays
def search_airport_by_iata_code(iata_code: str):
# TODO
# Retourne la ligne correspondant à l'aéroport portant le code iata "iata_code"
class Airport:
def __init__(self, iata_code, name, iso_country):
# TODO
# Constructeur de la classe
def delete(self):
# TODO
# Retire l'aéroport de la DB
def save(self):
# TODO
# Sauvegarde l'aéroport dans la DB
@staticmethod
def get(iata_code: str):
# Retourne un objet Aéroport construit à partir des informations de la DB
# récupérer à partir du code iata "iata_code"
# Retourne none si aucun aéroport avec le code iata "iata_code"
# se trouve dans la DB
# Vous pouvez vous insprirer de la classe Country implémentée précédemment
.. container:: code-block-caption
``mobility/models/airport.py``
.. raw:: html
Solution (Essayez d'abord par vous-même)
.. code-block:: python
from mobility.db import get_db
def get_airport_list():
db = get_db()
return db.execute(
'SELECT * FROM airport')
def search_airport_by_iata_code(iata_code: str):
db = get_db()
return db.execute('SELECT * FROM airport WHERE iata_code=?', (iata_code,)).fetchall()
class Airport:
def __init__(self, iata_code, name, iso_country):
self.iata_code = iata_code
self.name = name
self.iso_country = iso_country
def delete(self):
db = get_db()
db.execute("DELETE FROM airport WHERE iata_code=?", (self.iata_code,))
db.commit()
def save(self):
db = get_db()
db.execute("INSERT INTO aiport(iata_code,name, iso_country ) VALUES(?, ?, ?)", ( self.iata_code, self.name, self.iso_country))
db.commit()
@staticmethod
def get(iata_code: str):
db = get_db()
data = db.execute('SELECT * FROM airport WHERE iata_code=?', (iata_code,)).fetchone()
if data is None:
return None
else:
return Airport(data["iata_code"], data["name"], data["iso_country"])
.. raw:: html
Créez ensuite le fichier ``airport.py`` dans le dossier ``mobility``.
.. container:: literal-block-wrapper docutils
:name: idairportcontroller
.. container:: code-block-caption
``mobility/airport.py``
.. code-block:: python
from flask import (
Blueprint, redirect, render_template, request, url_for
)
from mobility.models.airport import Airport
from mobility.models.airport import get_airport_list,search_airport_by_iata_code
bp = Blueprint('airport', __name__)
# Define the routes code
@bp.route('/')
def airport_list():
# TODO
# Page principal qui affiche la liste des aéroports
# avec leur nom, code IATA et le nom de leur pays correspondant
@bp.route("/create_airport", methods=["POST"])
def airport_create():
# TODO
# Page permettant d'ajouter un aéroport, similaire à "create_country"
@bp.route("/delete_airport/")
def airport_delete(iata_code):
# TODO
# Page permettant de retirer un aéroport, similaire à "delete_country"
.. container:: literal-block-wrapper docutils
:name: idairportsolution
.. container:: code-block-caption
``mobility/airport.py``
.. raw:: html
Solution (Essayez d'abord par vous-même)
.. code-block:: python
from flask import (
Blueprint, redirect, render_template, request, url_for
)
from mobility.models.airport import Airport
from mobility.models.airport import get_airport_list,search_airport_by_iata_code
bp = Blueprint('airport', __name__)
# Define the routes code
@bp.route('/')
def airport_list():
airports = get_airport_list()
return render_template("airport.html", airports=airports)
@bp.route("/create_airport", methods=["POST"])
def airport_create():
iata_code = request.form["iata_code"]
if not search_airport_by_iata_code(str(iata_code)):
name = request.form["name"]
iso_country = request.form["iso_country"]
airport = Airport(iata_code, name, iso_country)
airport.save()
return redirect(url_for("airport.airport_list"))
@bp.route("/delete_airport/")
def airport_delete(iata_code):
airport = Airport.get(iata_code)
if airport:
airport.delete()
return redirect(url_for("airport.airport_list"))
.. raw:: html
Complétez le fichier ``airport.html`` pour avoir la fonctionnalité d'ajouter et de supprimer des aéroports à l'aide d'une interface semblable à ce que nous avons fait
pour les pays.
.. container:: literal-block-wrapper docutils
:name: idairporttemplate
.. container:: code-block-caption
``mobility/templates/airport.html``
.. raw:: html
Solution (Essayez d'abord par vous-même)
.. code-block:: html+jinja
{% extends "base.html" %}
{% block content %}
Enfin n'oubliez pas de mettre à jour le fichier ``__init__.py`` dans le dossier ``mobility`` en ajoutant et modifiant les lignes suivantes.
.. container:: literal-block-wrapper docutils
:name: id3
.. container:: code-block-caption
``mobility/__init__.py``
.. code-block:: python
from . import country, airport
app.register_blueprint(country.bp)
app.register_blueprint(airport.bp)
app.add_url_rule('/', endpoint='index')
Ajoutez un pays et puis un aéroport à votre base de données par le formulaire en utilisant le même code ISO. **Si vous ajoutez un aéroport avec un code ISO sans pays correspondant, l'aéroport ne sera pas affiché**.
Voici un exemple de ce que vous devriez voir sur la page ``airport.html``.
.. image:: ../_images/airport_final.png
:class: screenshot align-center
.. only:: html
Continuez en lisant :ref:`ref-sql-use-moodle-db`.