Jako dodatek do informacji w tym wątku: byłem trochę zdezorientowany zachowaniem flask.g
, ale kilka szybkich testów pomogło mi to wyjaśnić. Oto, co wypróbowałem:
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))
A oto wynik, który daje:
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
Jak powiedział wcześniej theY4Kman, „Każde żądanie przesyła nowy kontekst aplikacji”. I jak docs kolb powiedzieć , kontekst aplikacji „nie będą dzielone pomiędzy żądaniami”. To, co nie zostało wyraźnie powiedziane (chociaż wydaje mi się, że wynika to z tych stwierdzeń) i co jasno pokazuje moje testy, to fakt, że nigdy nie należy jawnie tworzyć wielu kontekstów żądań zagnieżdżonych w jednym kontekście aplikacji, ponieważ flask.g
(i co) tego nie robi. nie ma żadnej magii, dzięki której działa na dwóch różnych „poziomach” kontekstu, z różnymi stanami istniejącymi niezależnie na poziomach aplikacji i żądania.
W rzeczywistości „kontekst aplikacji” jest potencjalnie dość mylącą nazwą, ponieważ app.app_context()
jest to kontekst na żądanie , dokładnie taki sam jak „kontekst żądania” . Potraktuj to jako „kontekst żądania lite”, wymagany tylko w przypadku, gdy potrzebujesz niektórych zmiennych, które normalnie wymagają kontekstu żądania, ale nie potrzebujesz dostępu do żadnego obiektu żądania (np. Podczas wykonywania operacji wsadowych baz danych w Skrypt powłoki). Jeśli spróbujesz rozszerzyć kontekst aplikacji, aby obejmował więcej niż jeden kontekst żądania, prosisz o kłopoty. Więc zamiast mojego testu powyżej, powinieneś zamiast tego napisać taki kod z kontekstami Flaska:
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))
Co da oczekiwane rezultaty:
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
w wersji 0.10, w przeciwnym razie wygląda na to, że w dużej części kodu pojawią się przebiegłe błędy.