Utilisez un plan de flacon pour concevoir vos applications – Real Python

By | février 3, 2020

Cours Python en ligne

Flask est un cadre d'application Web très populaire qui laisse presque toutes les décisions de conception et d'architecture au développeur. Dans ce didacticiel, vous apprendrez comment un Plan de ballon, ou Plan pour faire court, peut vous aider à structurer votre application Flask en regroupant ses fonctionnalités en composants réutilisables.

Dans ce didacticiel, vous apprendrez:

  • Qu'est-ce que les plans Flask et comment ils fonctionnent
  • Comment créer et utiliser un plan de flacon pour organiser votre code
  • Comment améliorer la réutilisation du code à l'aide de votre propre plan ou d'un plan de flacon tiers

Ce didacticiel suppose que vous avez une certaine expérience de l'utilisation de Flask et que vous avez déjà créé certaines applications. Si vous n'avez jamais utilisé Flask auparavant, consultez les applications Web Python avec Flask (Tutorial Series).

À quoi ressemble une application Flask

Commençons par revoir la structure d'une petite application Flask. Vous pouvez créer une petite application Web en suivant les étapes de cette section. Pour commencer, vous devez installer le Ballon Paquet Python. Vous pouvez exécuter la commande suivante pour installer Flask à l'aide de pépin:

$ installer pip Ballon==1.1.1

La commande ci-dessus installe la version Flask 1.1.1. Il s'agit de la version que vous utiliserez tout au long de ce didacticiel, mais vous pouvez également appliquer ce que vous apprendrez ici à d'autres versions.

Après avoir installé Flask, vous êtes prêt à commencer à implémenter ses fonctionnalités. Comme Flask n'impose aucune restriction sur la structure du projet, vous pouvez organiser le code de votre projet comme vous le souhaitez. Pour votre première application, vous pouvez utiliser une mise en page très simple, comme indiqué ci-dessous. Un seul fichier contiendra toute la logique d'application:

Le fichier app.py contiendra la définition de l'application et ses vues.

Lorsque vous créez une application Flask, vous commencez par créer un Ballon objet qui représente votre application, puis vous associez vues à itinéraires. Flask s'occupe de répartir les demandes entrantes vers la vue correcte en fonction de l'URL de la demande et des itinéraires que vous avez définis.

Dans Flask, les vues peuvent être tout appelable (comme une fonction) qui reçoit demandes et retourne le réponse pour cette demande. Flask est responsable de l'envoi de la réponse à l'utilisateur.

Le bloc de code suivant est le code source complet de votre application:

de ballon importation Ballon

app = Ballon(__Nom__)

@app.route('/')
def indice():
    revenir "Ceci est un exemple d'application"

Ce code crée l'objet app, qui appartient à la Ballon classe. La fonction d'affichage indice() est lié à l'itinéraire / en utilisant le app.route décorateur. Pour en savoir plus sur les décorateurs, consultez Primer on Python Decorators et Python Decorators 101.

Vous pouvez exécuter l'application avec la commande suivante:

Par défaut, Flask exécutera l'application que vous avez définie dans app.py sur le port 5000. Pendant que l'application est en cours d'exécution, accédez à http: // localhost: 5000 en utilisant votre navigateur Web. Vous verrez une page affichant le message, Ceci est un exemple d'application.

La disposition de projet choisie est idéale pour les très petites applications, mais elle ne s’adapte pas bien. À mesure que votre code se développe, il peut devenir plus difficile pour vous de tout conserver dans un seul fichier. Ainsi, lorsque votre application augmente en taille ou en complexité, vous souhaiterez peut-être structure votre code d'une manière différente pour qu'il soit maintenable et clair à comprendre. Tout au long de ce didacticiel, vous apprendrez à utiliser un plan de flacon pour y parvenir.

À quoi ressemble un plan de flacon

Les plans des flacons encapsulent Fonctionnalité, telles que les vues, les modèles et d'autres ressources. Pour avoir un aperçu du fonctionnement d'un Blueprint Flask, vous pouvez refactoriser l'application précédente en déplaçant indice voir dans un plan de flacon. Pour ce faire, vous devez créer un plan de flacon contenant le indice afficher et ensuite l'utiliser dans l'application.

Voici à quoi ressemble la structure du fichier pour cette nouvelle application:

app /
|
├── app.py
└── example_blueprint.py

example_blueprint.py contiendra l'implémentation du Blueprint Flask. Vous allez ensuite modifier app.py pour l'utiliser.

Le bloc de code suivant montre comment vous pouvez implémenter ce Blueprint Flask dans example_blueprint.py. Il contient une vue sur l'itinéraire / qui renvoie le texte Ceci est un exemple d'application:

de ballon importation Plan

example_blueprint = Plan('example_blueprint', __Nom__)

@example_blueprint.route('/')
def indice():
    revenir "Ceci est un exemple d'application"

Dans le code ci-dessus, vous pouvez voir les étapes communes à la plupart des définitions de Blueprint Flask:

  1. Créer une Plan objet appelé example_blueprint.
  2. Ajouter vues à example_blueprint en utilisant le route décorateur.

Le bloc de code suivant montre comment votre application importe et utilise le Blueprint Flask:

de ballon importation Ballon
de example_blueprint importation example_blueprint

app = Ballon(__Nom__)
app.register_blueprint(example_blueprint)

Pour utiliser n'importe quel plan de flacon, vous devez l'importer puis S'inscrire dans l'application en utilisant register_blueprint (). Lorsqu'un plan de flacon est enregistré, l'application est étendue avec son contenu.

Vous pouvez exécuter l'application avec la commande suivante:

Pendant que l'application est en cours d'exécution, accédez à http: // localhost: 5000 en utilisant votre navigateur Web. Vous verrez une page affichant le message, Ceci est un exemple d'application.

Comment fonctionnent les plans des flacons

Dans cette section, vous apprendrez en détail comment un Blueprint Flask est implémenté et utilisé. Chaque plan de flacon est un objet qui fonctionne de manière très similaire à une application Flask. Ils peuvent tous deux avoir des ressources, telles que des fichiers statiques, des modèles et des vues associées aux itinéraires.

Cependant, un Blueprint Flask n'est pas réellement une application. Il doit être enregistré dans une application avant de pouvoir l'exécuter. Lorsque vous enregistrez un Blueprint Flask dans une application, vous êtes en fait extension l'application avec le contenu du Blueprint.

C'est le concept clé derrière tout plan de flacon. Ils enregistrent les opérations à exécuter ultérieurement lorsque vous les enregistrez sur une application. Par exemple, lorsque vous associez une vue à un itinéraire dans un Blueprint Flask, il enregistre cette association à effectuer plus tard dans l'application lorsque le Blueprint est enregistré.

Faire un plan de flacon

Revoyons la définition du plan de flacon que vous avez vue précédemment et examinons-la en détail. Le code suivant montre le Plan création d'objet:

de ballon importation Plan

example_blueprint = Plan('example_blueprint', __Nom__)

Notez que dans le code ci-dessus, certains arguments sont spécifiés lors de la création du Plan objet. Le premier argument, "example_blueprint", est le plan directeur Nom, qui est utilisé par le mécanisme de routage de Flask. Le deuxième argument, __Nom__, est le plan directeur nom d'importation, que Flask utilise pour localiser les ressources du Blueprint.

Il existe d'autres arguments facultatifs que vous pouvez fournir pour modifier le comportement du Blueprint:

  • dossier_ statique: le dossier où se trouvent les fichiers statiques du Blueprint

  • static_url_path: l'URL de diffusion des fichiers statiques

  • dossier_modèle: le dossier contenant les modèles du Blueprint

  • url_prefix: le chemin à ajouter à toutes les URL du Blueprint

  • sous-domaine: le sous-domaine sur lequel les itinéraires de ce Blueprint correspondront par défaut

  • url_defaults: un dictionnaire des valeurs par défaut que les vues de ce Blueprint recevront

  • root_path: le chemin du répertoire racine du Blueprint, dont la valeur par défaut est obtenue à partir du nom d'importation du Blueprint

Notez que tous les chemins, sauf root_path, sont relatifs au répertoire du Blueprint.

le Plan objet example_blueprint possède des méthodes et des décorateurs qui vous permettent d'enregistrer des opérations à exécuter lors de l'enregistrement du Blueprint Flask dans une application pour l'étendre. L'un des décorateurs les plus utilisés est route. Il vous permet d'associer une fonction d'affichage à un itinéraire URL. Le bloc de code suivant montre comment ce décorateur est utilisé:

@example_blueprint.route('/')
def indice():
    revenir "Ceci est un exemple d'application"

Vous décorez indice() en utilisant example_blueprint.route et associer la fonction à l'URL /.

Plan Les objets fournissent également d'autres méthodes qui peuvent vous être utiles:

  • .errorhandler () pour enregistrer une fonction de gestion des erreurs
  • .before_before () () exécuter une action avant chaque requête
  • .after_request () pour exécuter une action après chaque demande
  • .app_template_filter () enregistrer un filtre de modèle au niveau de l'application

Vous pouvez en savoir plus sur l'utilisation de Blueprints et du Plan dans la documentation Flask Blueprints.

Enregistrement du Blueprint dans votre application

Rappelons qu'un Blueprint Flask n'est pas réellement une application. Lorsque vous enregistrez le Flask Blueprint dans une application, vous étendre l'application avec son contenu. Le code suivant montre comment vous pouvez enregistrer le Blueprint Flask précédemment créé dans une application:

de ballon importation Ballon
de example_blueprint importation example_blueprint

app = Ballon(__Nom__)
app.register_blueprint(example_blueprint)

Quand vous appelez .register_blueprint (), vous appliquez toutes les opérations enregistrées dans le plan de flacon example_blueprint à app. Maintenant, les demandes à l'URL pour l'URL / sera servi en utilisant .indice() du plan de flacon.

Vous pouvez personnaliser la manière dont Flask Blueprint étend l'application en fournissant certains paramètres à register_blueprint:

  • url_prefix est un préfixe facultatif pour tous les itinéraires du Blueprint.
  • sous-domaine est un sous-domaine auquel les itinéraires Blueprint correspondront.
  • url_defaults est un dictionnaire avec des valeurs par défaut pour les arguments de vue.

La possibilité de faire une certaine personnalisation au moment de l'inscription, plutôt qu'au moment de la création, est particulièrement utile lorsque vous partagez le même plan de flacon dans différents projets.

Dans cette section, vous avez vu comment fonctionnent les Blueprint et comment les créer et les utiliser. Dans les sections suivantes, vous apprendrez comment tirer parti d'un plan de flacon pour architecte vos applications, en les structurant en composants indépendants. Dans certains cas, il vous est également possible de réutiliser ces composants dans différentes applications pour réduire le temps de développement!

Comment utiliser les plans de flacons pour concevoir le code de votre application

Dans cette section, vous allez voir comment vous pouvez refactor un exemple d'application utilisant un Blueprint Flask. L'exemple d'application est un commerce électronique site avec les fonctionnalités suivantes:

  • Les visiteurs peuvent s'inscrire, se connecter et récupérer mots de passe.
  • Les visiteurs peuvent rechercher des produits et afficher leurs détails.
  • Les utilisateurs peuvent ajouter des produits à leur Chariot et caisse.
  • Une API permet aux systèmes externes de rechercher et de récupérer Information produit.

Vous n'avez pas besoin de vous soucier des détails de la mise en œuvre. Au lieu de cela, vous vous concentrerez principalement sur la façon dont un Blueprint Flask peut être utilisé pour améliorer l'architecture de l'application.

Comprendre pourquoi la disposition du projet est importante

N'oubliez pas que Flask n'applique aucune disposition de projet particulière. Il est tout à fait possible d'organiser le code de cette application comme suit:

commerce électronique/
|
├── statique /
| ├── logo.png
| ├── main.css
| ├── generic.js
| └── product_view.js
|
├── modèles /
| ├── login.html
| ├── Forgot_password.html
| ├── signup.html
| ├── checkout.html
| ├── cart_view.html
| ├── index.html
| ├── liste_produits.html
| └── product_view.html
|
├── app.py
├── config.py
└── models.py

Le code de cette application est organisé en utilisant ces répertoires et fichiers:

  • statique/ contient les fichiers statiques de l'application.
  • modèles / contient les modèles de l'application.
  • models.py contient la définition des modèles de l'application.
  • app.py contient la logique d'application.
  • config.py contient les paramètres de configuration de l'application.

Ceci est un exemple du nombre d'applications qui commencent. Bien que cette mise en page soit assez simple, elle présente plusieurs inconvénients qui surviennent à mesure que la complexité de l'application augmente. Par exemple, il vous sera difficile de réutiliser la logique d'application dans d'autres projets car toutes les fonctionnalités sont regroupées dans app.py. Si vous divisez cette fonctionnalité en modules à la place, vous pouvez réutiliser des modules complets dans différents projets.

De plus, si vous n'avez qu'un seul fichier pour la logique d'application, vous vous retrouverez avec un très grand app.py qui mélange du code presque sans rapport. Cela peut rendre difficile la navigation et la maintenance du script.

De plus, les gros fichiers de code sont une source de conflits lorsque vous travaillez en équipe, car tout le monde apportera des modifications au même fichier. Ce ne sont que quelques raisons pour lesquelles la disposition précédente n'est bonne que pour les très petites applications.

Organiser vos projets

Au lieu de structurer l'application à l'aide de la mise en page précédente, vous pouvez tirer parti d'un plan directeur de flacon pour diviser le code en différents modules. Dans cette section, vous allez voir comment architecturer l'application précédente pour créer des Blueprints qui encapsulent les fonctionnalités associées. Dans cette disposition, il y a cinq plans de flacon:

  1. Plan d'API pour permettre aux systèmes externes de rechercher et de récupérer des informations sur les produits
  2. Plan d'authentification pour permettre aux utilisateurs de se connecter et de récupérer leur mot de passe
  3. Plan du chariot pour la fonctionnalité de panier et de paiement
  4. Plan général pour la page d'accueil
  5. Plan de produits pour rechercher et visualiser des produits

Si vous utilisez un répertoire distinct pour chaque Blueprint Flask et ses ressources, la disposition du projet se présenterait comme suit:

commerce électronique/
|
├── api /
| ├── __init__.py
| └── api.py
|
├── auth /
| ├── modèles /
| | └── auth /
| | ├── login.html
| | ├── Forgot_password.html
| | └── signup.html
| |
| ├── __init__.py
| └── auth.py
|
├── chariot /
| ├── modèles /
| | └── chariot /
| | ├── checkout.html
| | └── view.html
| |
| ├── __init__.py
| └── cart.py
|
├── général /
| ├── modèles /
| | └── général /
| | └── index.html
| |
| ├── __init__.py
| └── general.py
|
├── produits /
| ├── statique /
| | └── view.js
| |
| ├── modèles /
| | └── produits /
| | ├── list.html
| | └── view.html
| |
| ├── __init__.py
| └── products.py
|
├── statique /
| ├── logo.png
| ├── main.css
| └── generic.js
|
├── app.py
├── config.py
└── models.py

Pour organiser le code de cette manière, vous déplacez toutes les vues de app.py dans le plan de flacon correspondant. Vous avez également déplacé des modèles et des fichiers statiques non globaux. Cette structure vous permet de trouver plus facilement le code et les ressources liés à une fonctionnalité donnée. Par exemple, si vous souhaitez trouver la logique d'application des produits, vous pouvez accéder au plan directeur des produits dans produits / produits.py au lieu de faire défiler app.py.

Voyons l'implémentation du Blueprint Produits dans produits / produits.py:

de ballon importation Plan, render_template
de ecommerce.models importation Produit

products_bp = Plan('products_bp', __Nom__,
    template_folder='modèle',
    dossier_ statique='statique', static_url_path='les atouts')

@products_bp.route('/')
def liste():
    des produits = Produit.requete.tout()
    revenir render_template('produits / list.html', des produits=des produits)

@products_bp.route('/vue/")
def vue(product_id):
    produit = Produit.requete.avoir(product_id)
    revenir render_template('produits / view.html', produit=produit)

Ce code définit le products_bp Flask Blueprint et contient uniquement le code lié aux fonctionnalités du produit. Étant donné que ce plan de ballon a ses propres modèles, vous devez spécifier le template_folder par rapport à la racine du Blueprint dans le Plan création d'objets. Puisque vous spécifiez static_folder = 'statique' et static_url_path = 'actifs', fichiers dans commerce électronique / produits / statique / sera servi sous la /les atouts/ URL.

Vous pouvez maintenant déplacer le reste des fonctionnalités de votre code vers le plan de flacon correspondant. En d'autres termes, vous pouvez créer des Blueprints pour l'API, l'authentification, le panier et les fonctionnalités générales. Une fois que vous avez terminé, le seul code restant dans app.py sera un code qui traite de l'initialisation de l'application et de l'enregistrement du plan de flacon:

de ballon importation Ballon

de ecommmerce.api.api importation api_bp
de ecommmerce.auth.auth importation auth_bp
de ecommmerce.cart.cart importation cart_bp
de ecommmerce.general.general importation general_bp
de ecommmerce.products.products importation products_bp

app = Ballon(__Nom__)

app.register_blueprint(api_bp, url_prefix='/ api')
app.register_blueprint(auth_bp)
app.register_blueprint(cart_bp, url_prefix='/Chariot')
app.register_blueprint(general_bp)
app.register_blueprint(products_bp, url_prefix='/des produits')

Maintenant, app.py importe et enregistre simplement les Blueprints pour étendre l'application. Depuis que vous utilisez url_prefix, vous pouvez éviter les collisions d'URL entre les itinéraires Flask Blueprint. Par exemple, les URL /des produits/ et /Chariot/ résoudre à différents points finaux définis dans le products_bp et cart_bp Plans pour le même itinéraire, /.

Y compris les modèles

Dans Flask, lorsqu'une vue affiche un modèle, le fichier de modèle est recherché dans tous les répertoires enregistrés dans le chemin de recherche de modèle. Par défaut, ce chemin est ["/templates"], les modèles ne sont donc recherchés que dans le / modèles dans le répertoire racine de l'application.

Si vous définissez template_folder dans la création d'un Blueprint, puis son dossier de modèles est ajouté au chemin de recherche de modèle de l'application lorsque le Blueprint Flask est enregistré. Cependant, s'il existe des chemins de fichier dupliqués sous différents répertoires qui font partie du chemin de recherche de modèle, alors on aura priorité, en fonction de leur ordre d'inscription.

Par exemple, si une vue demande le modèle view.html et il y a des fichiers portant ce même nom dans différents répertoires du chemin de recherche du modèle, alors l'un d'entre eux aura la priorité sur l'autre. Comme il peut être difficile de se souvenir de l'ordre de priorité, il vaut mieux éviter d'avoir des fichiers sous le même chemin dans différents répertoires de modèles. C'est pourquoi la structure suivante pour les modèles de l'application est logique:

commerce électronique/
|
└── produits /
    └── modèles /
        └── produits /
            ├── search.html
            └── view.html

Au début, il peut sembler redondant que le nom du plan de flacon apparaisse deux fois:

  1. Comme le Blueprint racine annuaire
  2. À l'intérieur de modèles annuaire

Cependant, sachez qu'en faisant cela, vous pouvez éviter collisions de noms de modèles entre différents Blueprints. En utilisant cette structure de répertoires, toutes les vues nécessitant le view.html modèle pour les produits peut utiliser produits / view.html comme nom de fichier modèle lors de l'appel render_template. Cela évite les conflits avec le view.html qui appartient au Cart Blueprint.

Pour terminer, il est important de savoir que les modèles dans le modèle répertoire ont priorité plus grande que ceux du répertoire de modèles de Blueprint. Cela peut être utile de savoir si vous souhaitez remplacer les modèles de Blueprint sans modifier réellement le fichier de modèle.

Par exemple, si vous souhaitez remplacer le modèle produits / view.html dans le plan directeur des produits, vous pouvez y parvenir en créant un nouveau fichier produits / view.html Dans l'application modèles annuaire:

commerce électronique/
|
├── produits /
| └── modèles /
| └── produits /
| ├── search.html
| └── view.html
|
└── modèles /
        └── produits /
            └── view.html

Lorsque vous faites cela, votre programme utilisera templates / produits / view.html au lieu de produits / modèles / produits / view.html chaque fois qu'une vue nécessite le modèle produits / view.html.

Fournir des fonctionnalités autres que des vues

Jusqu'à présent, vous n'avez vu que des Blueprints qui étendent des applications avec des vues, mais les Flask Blueprints n'ont pas à fournir uniquement des vues! Ils peuvent étendre les applications avec modèles, fichiers statiques et filtres de modèles. Par exemple, vous pouvez créer un Plan de ballon pour fournir un ensemble d'icônes et l'utiliser dans toutes vos applications. Ce serait la structure de fichiers pour un tel Blueprint:

app /
|
└── icônes /
    ├── statique /
    | ├── add.png
    | ├── remove.png
    | └── save.png
    |
    ├── __init__.py
    └── icons.py

le statique dossier contient les fichiers d’icônes et icons.py est la définition de Blueprint Flask.

C'est ainsi icons.py pourrait ressembler:

de ballon importation Plan

icons_bp = Plan('icons_bp', __Nom__,
    dossier_ statique='statique',
    static_url_path='Icônes')

Ce code définit le icons_bp Flask Blueprint qui expose les fichiers dans le répertoire statique sous le /Icônes/ URL. Notez que ce Blueprint ne définit aucun itinéraire.

Lorsque vous pouvez créer des Blueprints qui regroupent des vues et d'autres types de contenu, vous rendez votre code et vos actifs plus réutilisables dans vos applications. Pour en savoir plus sur la réutilisabilité de Flask Blueprint, consultez la section suivante.

Comment utiliser les plans de flacon pour améliorer la réutilisation du code

Outre l'organisation du code, il existe un autre avantage à structurer votre application Flask en tant que collection de composants indépendants. Vous pouvez réutiliser ces composants même dans différentes applications! Par exemple, si vous avez créé un Blueprint Flask qui fournit des fonctionnalités pour un formulaire de contact, vous pouvez le réutiliser dans toutes vos applications.

Vous pouvez également utiliser les Blueprints créés par d'autres développeurs pour accélérer votre travail. Bien qu'il n'y ait pas de référentiel centralisé pour les plans Flask existants, vous pouvez les trouver à l'aide de l'index de package Python, de la recherche GitHub et des moteurs de recherche Web. Vous pouvez en savoir plus sur la recherche de packages PyPI dans Qu'est-ce que Pip? Un guide pour les nouveaux pythonistes.

Il existe différents plans de flacons et Extensions de flacon (qui sont implémentées à l'aide de Blueprints) qui fournissent des fonctionnalités qui peuvent vous être utiles:

  • Authentification
  • Génération Admin / CRUD
  • Fonctionnalité CMS
  • Et plus!

Au lieu de coder votre application à partir de zéro, vous pouvez envisager de rechercher un plan ou une extension Flask existant que vous pouvez réutiliser. Tirer parti des Blueprints et Extensions tiers peut vous aider à réduire le temps de développement et à rester concentré sur la logique principale de votre application!

Conclusion

Dans ce didacticiel, vous avez vu comment fonctionnent les Blueprint, comment les utiliser et comment ils peuvent vous aider à organiser le code de votre application. Les plans de flacons sont un excellent outil pour gérer la complexité des applications à mesure qu'elles augmentent.

Vous avez appris:

  • Quoi Plans de flacon sont et comment ils fonctionnent
  • Comment tu peux mettre en œuvre et utiliser un plan de flacon
  • Comment Flask Blueprints peut vous aider à organiser le code de votre application
  • Comment vous pouvez utiliser les plans des flacons pour réutilisabilité de vos propres composants et de composants tiers
  • Comment l'utilisation d'un Blueprint Flask dans votre projet peut réduire le temps de développement

Vous pouvez utiliser ce que vous avez appris dans ce didacticiel pour commencer à organiser vos applications sous la forme d'un ensemble de plans directeurs. Lorsque vous architecturez vos applications de cette façon, vous améliorez la réutilisation du code, la maintenabilité et le travail d'équipe!