J'essaie de créer une "application modulaire" dans Flask en utilisant Blueprints.
Cependant, lors de la création de modèles, je me heurte au problème suivant : je dois faire référence à l'application afin d'obtenir l'adresse de l'utilisateur. db
-fourni par Flask-SQLAlchemy. J'aimerais pouvoir utiliser certains blueprints avec plus d'une application (de manière similaire à la façon dont les applications Django peuvent être utilisées), ce n'est donc pas une bonne solution.*
- Il est possible d'inverser les choses et de faire en sorte que le Blueprint crée l'image de l'utilisateur.
db
que l'application importe ensuite avec le reste du blueprint. Mais alors, tout autre blueprint souhaitant créer des modèles doit importer de que au lieu de l'application.
Mes questions sont donc les suivantes :
- Existe-t-il un moyen de laisser les Blueprints définir des modèles sans tenir compte de l'application dans laquelle ils sont utilisés par la suite - et de faire en sorte que plusieurs Blueprints se rejoignent ? Je veux dire par là qu'il faut importer le module/paquet de l'application à partir de votre Blueprint.
- Ai-je tort dès le départ ? Les Blueprints ne sont-ils pas censés être indépendants de l'application et être redistribuables (à la manière des applications Django) ?
- Si non, alors quel modèle devrait que vous utilisez pour créer quelque chose comme ça ? Des extensions Flask ? Devriez-vous simplement ne pas le faire -- et peut-être centraliser tous les modèles/schémas à la Ruby on Rails ?
Modifier : J'ai réfléchi à cette question moi-même maintenant, et cela pourrait être plus lié à SQLAlchemy qu'à Flask parce que vous devez avoir l'
declarative_base()
lors de la déclaration des modèles. Et c'est doit bien venir de quelque part, de toute façon !La meilleure solution consiste peut-être à définir le schéma de votre projet en un seul endroit et à le diffuser, comme le fait Ruby on Rails. Les définitions déclaratives des classes SQLAlchemy ressemblent davantage à schema.rb qu'à models.py de Django. J'imagine que cela rendrait également plus facile l'utilisation des migrations (de alambic ou sqlalchemy-migrate ).
On m'a demandé de fournir un exemple, alors faisons quelque chose de simple : Disons que j'ai un plan décrivant des "pages plates" -- un contenu simple et "statique" stocké dans la base de données. Il utilise une table avec juste un nom court (pour les URLs), un titre et un corps. Ceci est simple_pages/__init__.py
:
from flask import Blueprint, render_template
from .models import Page
flat_pages = Blueprint('flat_pages', __name__, template_folder='templates')
@flat_pages.route('/<page>')
def show(page):
page_object = Page.query.filter_by(name=page).first()
return render_template('pages/{}.html'.format(page), page=page_object)
Ensuite, il serait bien de laisser ce blueprint définir son propre modèle (ceci en simple_page/models.py
) :
# TODO Somehow get ahold of a `db` instance without referencing the app
# I might get used in!
class Page(db.Model):
name = db.Column(db.String(255), primary_key=True)
title = db.Column(db.String(255))
content = db.Column(db.String(255))
def __init__(self, name, title, content):
self.name = name
self.title = title
self.content = content
Cette question est liée à :
- Problème d'importation/contexte de Flask-SQLAlchemy
- Quelle est la disposition des dossiers pour une application Flask divisée en modules ?
Et d'autres encore, mais toutes les réponses semblent dépendre de l'importation de l'application. db
ou l'inverse. Le site "Large app how to" La page wiki utilise également le modèle "importer votre application dans votre blueprint".
* Puisque la documentation officielle montre comment créer des routes, des vues, des modèles et des ressources dans un Blueprint sans se soucier de l'application dans laquelle il se trouve, j'ai supposé que les Blueprints devraient, en général, être réutilisables entre les applications. Cependant, cette modularité ne semble pas <em>que </em>utile sans disposer également de modèles indépendants.
Étant donné que les Blueprints peuvent être reliés à une application plusieurs fois, il se peut que ce soit simplement une mauvaise approche que d'avoir des modèles dans les Blueprints ?