J'ai vu que g
cela passerait du contexte de la requête au contexte de l'application dans Flask 0.10, ce qui m'a rendu confus quant à l'utilisation prévue de g
.
Ma compréhension (pour Flask 0.9) est que:
g
vit dans le contexte de la requête, c'est-à-dire, créé à nouveau lorsque les requêtes commencent, et disponible jusqu'à la fing
est destiné à être utilisé comme un "tableau noir de demande", où je peux mettre des éléments pertinents pour la durée de la demande (c'est-à-dire définir un drapeau au début de la demande et le gérer à la fin, éventuellement à partir d'une pairebefore_request
/after_request
)- en plus de conserver l'état au niveau de la demande,
g
peut et doit être utilisé pour la gestion des ressources, c'est-à-dire pour la conservation des connexions à la base de données, etc.
Laquelle de ces phrases n'est plus vraie dans Flask 0.10? Quelqu'un peut-il me diriger vers une ressource discutant des raisons du changement? Que dois-je utiliser comme «tableau noir de demande» dans Flask 0.10 - dois-je créer mon propre proxy thread-local spécifique à une application / extension et le pousser vers la pile de contexte before_request
? Quel est l'intérêt de la gestion des ressources au niveau du contexte applicatif, si mon application vit longtemps (pas comme une requête) et donc les ressources ne sont jamais libérées?
g
dans 0.10, sinon il semble que beaucoup de code pourrait commencer à développer des bogues sournois.flask.g
. speakerdeck.com/mitsuhiko/advanced-flask-patterns-1Réponses:
Advanced Flask Patterns , tel que lié par Markus , explique certains des changements apportés à la version
g
0.10:g
vit maintenant dans le contexte de l'application.g
peut toujours être utilisé pour définir des indicateurs par demande sans changement de code.teardown_request
été appelé. (La présentation d'Armin explique que cela est dû au fait que des choses comme la création de connexions à la base de données sont des tâches qui configurent l'environnement pour la requête, et ne doivent pas être gérées à l'intérieurbefore_request
etafter_request
)la source
app_ctx is None or app_ctx.app != self.app
vaut False, l'ancien contexte d'application semble être réutilisé? Cela ne semble pas correct, car le contexte de l'application "ne sera pas partagé entre les demandes" ...app.app_context()
? Si tel est le cas, il convient de noter qu'ilapp_context()
instancie un nouveau contexte d'application à chaque appel - il ne réutilise jamais un contexte.app_ctx is not None and app_ctx.app == self.app
, laapp_ctx = self.app.app_context()
ligne n'est pas exécutée; seulself._implicit_app_ctx_stack.append(None)
est exécuté dans ce cas.RequestContext
est poussé, donc un seulAppContext
est poussé. Mais si le mode de débogage est activé et qu'une requête échoue, Flask enregistre le contexte afin qu'il puisse être utilisé avec le débogueur .None
est ajouté au_app_ctx_stack
, donc lorsque la demande est supprimée, il sait ne pas encore apparaîtreAppContext
. La même chose se produit avec le client de test, qui conserve le contexte, donc il peut être inspecté.En complément aux informations de ce fil: j'ai été un peu confus par le comportement de
flask.g
moi aussi, mais quelques tests rapides m'ont aidé à le clarifier. Voici ce que j'ai essayé:Et voici le résultat qu'il donne:
Comme l'a dit theY4Kman ci-dessus, "Chaque requête pousse un nouveau contexte d'application". Et comme le dit la documentation Flask , le contexte de l'application "ne sera pas partagé entre les requêtes". Maintenant, ce qui n'a pas été explicitement déclaré (bien que je suppose que cela soit implicite de ces déclarations), et ce que mes tests montrent clairement, c'est que vous ne devriez jamais créer explicitement plusieurs contextes de demande imbriqués dans un contexte d'application, car
flask.g
(and co) doesn ' t avoir une magie par laquelle il fonctionne dans les deux différents "niveaux" de contexte, avec différents états existant indépendamment au niveau de l'application et de la demande.La réalité est que "contexte d'application" est potentiellement un nom assez trompeur, car
app.app_context()
c'est un contexte par demande , exactement le même que le "contexte de demande" . Considérez-le comme un «contexte de requête allégé», uniquement requis dans le cas où vous avez besoin de certaines des variables qui nécessitent normalement un contexte de requête, mais vous n'avez pas besoin d'accéder à un objet de requête (par exemple, lors de l'exécution d'opérations DB par lots dans un script shell). Si vous essayez d'étendre le contexte de l'application pour englober plus d'un contexte de demande, vous demandez des problèmes. Donc, plutôt que mon test ci-dessus, vous devriez plutôt écrire du code comme celui-ci avec les contextes de Flask:Ce qui donnera les résultats attendus:
la source