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 %}

Airports list

{% for airport in airports %} {% endfor %}
IATA code Name Country
{{ airport['iata_code'] }} {{ airport['name'] }} {{ airport['cname'] }} Delete

New airport

{% endblock %} .. raw:: html
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`.