Plusieurs Applications
Le contexte de l'application (et de son but), est en effet à confusion jusqu'à ce que vous vous rendez compte que le Flacon peut avoir de multiples applications. Imaginez la situation où vous voulez avoir un seul WSGI de l'interpréteur Python exécuter plusieurs Fiole d'application. Nous ne parlons pas des Modèles ici, nous parlons d'entièrement différent Flacon applications.
Vous pouvez définir ce similaire à la Fiole de section de documentation sur l'Application "Dispatching" exemple:
from werkzeug.wsgi import DispatcherMiddleware
from frontend_app import application as frontend
from backend_app import application as backend
application = DispatcherMiddleware(frontend, {
'/backend': backend
})
Notez qu'il existe deux types complètement différents Flacon applications en cours de création "frontend" et "backend". En d'autres termes, l' Flask(...)
application constructeur a été appelé à deux reprises, la création de deux instances d'un Flacon d'application.
Contextes
Lorsque vous travaillez avec Flacon, vous finissent souvent par l'utilisation de variables globales pour l'accès aux différentes fonctionnalités. Par exemple, vous avez probablement un code qui lit...
from flask import request
Puis, au cours d'une vue, vous pouvez utiliser request
d'accéder à l'information de la demande actuelle. De toute évidence, request
n'est pas normal variable globale; en réalité, il s'agit d'un contexte local de la valeur. En d'autres termes, il y a de la magie derrière les scènes qui dit "quand je l'appelle request.path
, obtenir l' path
de l'attribut de l' request
objet de la demande ACTUELLE." Deux demandes différentes auront des résultats différents pour request.path
. En fait, même si vous exécutez Flacon avec plusieurs threads, le Flacon est assez intelligent pour garder l' request
variable tellement isolé que deux threads peuvent appeler request.path
dans le même temps, et chacun serait d'obtenir la demande spécifique de leur fils.
De les mettre Ensemble
Nous avons déjà vu que le Flacon peut gérer plusieurs applications d'un même interprète, et aussi qu'en raison de la façon dont Flacon permet d'utiliser les "contexte local" globals il doit y avoir un mécanisme pour déterminer ce que le "courant" demande est (pour faire des choses telles que l' request.path
).
Mettre ces idées ensemble, il convient également de sens que le Flacon doit avoir une certaine manière de déterminer ce que le "courant" demande est!
Vous avez sans doute aussi avoir un code semblable au suivant:
from flask import url_for
Comme notre request
exemple, l' url_for
de la fonction de la logique qui dépend de l'environnement actuel. Dans ce cas, cependant, il est évident de voir que la logique est fortement dépendante de l'application qui est considéré comme le "courant" de l'app. Dans le frontend/backend exemple montré ci-dessus, à la fois le "frontend" et "backend" apps pourrait avoir un "/login" la route, et donc, url_for('/login')
doit retourner quelque chose de différent selon si l'affichage est en charge de la demande pour le frontend ou backend app.
Pour répondre à vos questions...
Quel est le but de la "pile" quand il s'agit de la demande ou
le contexte de l'application?
À partir du Contexte de Demande de docs:
Parce que le contexte de la demande est maintenue en interne comme une pile
peut push et pop à plusieurs reprises. Ce qui est très pratique à mettre en œuvre
des choses comme les redirections internes.
En d'autres termes, même si vous l'aura généralement 0 ou 1 articles sur ces pile de "actuelles les demandes" ou "actuel" des applications, il est possible que vous pourriez avoir plus.
L'exemple donné est l'endroit où vous avez votre demande de retour les résultats d'une "redirection interne". Disons qu'un utilisateur demande un, mais que vous voulez revenir à l'utilisateur B. Dans la plupart des cas, vous émettez une redirection de l'utilisateur, et l'utilisateur de la ressource B, indiquant que l'utilisateur exécute une deuxième demande pour récupérer B. d'Une manière légèrement différente de la manipulation de ce serait de faire une redirection interne, ce qui signifie que pendant le traitement, Flacon va faire une nouvelle demande à lui-même pour B de ressource, et d'utiliser les résultats de cette deuxième demande que les résultats de l'utilisateur d'origine de la demande.
Ce sont ces deux charges distinctes, ou sont-ils tous deux partie d'une pile?
Ils sont deux charges distinctes. Cependant, c'est un détail d'implémentation. Ce qui est plus important n'est pas tellement qu'il y est une pile, mais le fait qu'à tout moment, vous pouvez obtenir le "courant" de l'app ou de la demande (en haut de la pile).
Est le contexte de la demande poussé sur une pile ou une pile de lui-même?
Un "contexte de demande" est un élément de la "demande de la pile de contexte". De la même façon avec l'application "contexte" et "app contexte de la pile".
Suis-je capable de push/pop de multiples contextes sur eachother? Si oui,
pourquoi voudrais-je faire?
Dans une Fiole de l'application, vous devriez pas faire cela. Un exemple de cas où vous pourriez voulez est pour une redirection interne (décrit ci-dessus). Même dans ce cas, cependant, vous auriez probablement finir par avoir Flacon de traiter une nouvelle demande, et ainsi de Fiole de les pousser ou popping pour vous.
Cependant, il y a certains cas où vous seriez amené à manipuler la pile vous-même.
L'exécution du code en dehors d'une demande
Un problème typique des gens ont, c'est qu'ils utilisent le Flacon de SQLAlchemy extension pour configurer une base de données SQL et la définition d'un modèle à l'aide de code quelque chose comme ce qui est montré ci-dessous...
app = Flask(__name__)
db = SQLAlchemY() # Initialize the Flask-SQLAlchemy extension object
db.init_app(app)
Ensuite, à l' app
et db
valeurs dans un script qui doit être exécuté à partir de la coquille. Par exemple, un "setup_tables.py" le script...
from myapp import app, db
# Set up models
db.create_all()
Dans ce cas, le Flacon-SQLAlchemy extension sait à propos de l' app
application, mais au cours create_all()
il lèvera une erreur se plaindre de l'absence d'un contexte d'application. Cette erreur est justifiée; la gestion du contexte de l'application est déjà géré par Flacon lorsque l'application est le traitement d'une demande, mais depuis l' create_all()
méthode n'est PAS à exécuter lors d'un point de vue, le Flacon n'est pas le contexte pour vous.
La résolution est de pousser le contexte de l'application vous-même, ce qui peut être fait en faisant...
from myapp import app, db
# Set up models
with app.app_context():
db.create_all()
Ce sera le pousser un nouveau contexte de l'application (à l'aide de l'application de l' app
, rappelez-vous, il pourrait y avoir plus d'une application).
Les tests
Un autre cas où vous souhaitez manipuler la pile est utilisé pour les tests. Vous pouvez créer un test unitaire qui gère une demande et vous de vérifier les résultats:
import unittest
from flask import request
class MyTest(unittest.TestCase):
def test_thing(self):
with app.test_request_context('/?next=http://example.com/') as ctx:
# You can now view attributes on request context stack by using at `request`.
# Now the request context stack is empty