Como una adición a la información en este hilo: también me ha confundido un poco el comportamiento flask.g
, pero algunas pruebas rápidas me han ayudado a aclararlo. Esto es lo que probé:
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
print('in app context, before first request context')
print('setting g.foo to abc')
g.foo = 'abc'
print('g.foo should be abc, is: {0}'.format(g.foo))
with app.test_request_context():
print('in first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
print('setting g.foo to xyz')
g.foo = 'xyz'
print('g.foo should be xyz, is: {0}'.format(g.foo))
print('in app context, after first request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
with app.test_request_context():
print('in second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
print('setting g.foo to pqr')
g.foo = 'pqr'
print('g.foo should be pqr, is: {0}'.format(g.foo))
print('in app context, after second request context')
print('g.foo should be abc, is: {0}'.format(g.foo))
Y aquí está la salida que da:
in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be abc, is: abc
setting g.foo to xyz
g.foo should be xyz, is: xyz
in app context, after first request context
g.foo should be abc, is: xyz
in second request context
g.foo should be abc, is: xyz
setting g.foo to pqr
g.foo should be pqr, is: pqr
in app context, after second request context
g.foo should be abc, is: pqr
Como dijo el Y4Kman arriba, "Cada solicitud empuja un nuevo contexto de aplicación". Y como dicen los documentos de Flask , el contexto de la aplicación "no se compartirá entre las solicitudes". Ahora, lo que no se ha declarado explícitamente (aunque supongo que está implícito en estas declaraciones), y lo que mis pruebas muestran claramente, es que nunca debes crear explícitamente múltiples contextos de solicitud anidados dentro de un contexto de aplicación, porque flask.g
(y co) no No tiene ninguna magia por la que funcione en los dos diferentes "niveles" de contexto, con diferentes estados existentes independientemente en los niveles de solicitud y solicitud.
La realidad es que "contexto de aplicación" es potencialmente un nombre bastante engañoso, porque app.app_context()
es un contexto por solicitud , exactamente igual al "contexto de solicitud" . Piense en ello como un "contexto de solicitud lite", solo requerido en el caso de que necesite algunas de las variables que normalmente requieren un contexto de solicitud, pero no necesita acceso a ningún objeto de solicitud (por ejemplo, cuando se ejecutan operaciones de base de datos por lotes en un script de shell). Si intenta extender el contexto de la aplicación para abarcar más de un contexto de solicitud, está buscando problemas. Entonces, en lugar de mi prueba anterior, debería escribir código como este con los contextos de Flask:
from flask import Flask, g
app = Flask(__name__)
with app.app_context():
print('in app context, before first request context')
print('setting g.foo to abc')
g.foo = 'abc'
print('g.foo should be abc, is: {0}'.format(g.foo))
with app.test_request_context():
print('in first request context')
print('g.foo should be None, is: {0}'.format(g.get('foo')))
print('setting g.foo to xyz')
g.foo = 'xyz'
print('g.foo should be xyz, is: {0}'.format(g.foo))
with app.test_request_context():
print('in second request context')
print('g.foo should be None, is: {0}'.format(g.get('foo')))
print('setting g.foo to pqr')
g.foo = 'pqr'
print('g.foo should be pqr, is: {0}'.format(g.foo))
Lo que dará los resultados esperados:
in app context, before first request context
setting g.foo to abc
g.foo should be abc, is: abc
in first request context
g.foo should be None, is: None
setting g.foo to xyz
g.foo should be xyz, is: xyz
in second request context
g.foo should be None, is: None
setting g.foo to pqr
g.foo should be pqr, is: pqr
g
en 0.10, de lo contrario, parece que mucho código podría comenzar a desarrollar algunos errores tortuosos.