app.yaml - it's time to figure out how to make the application respond correctly to them. This is how our mappings look like:# $ Id: app.yaml 4 2010-01-25 12: 14: 48Z sigizmund $ application: helloworld version: 1 runtime: python api_version: 1 handlers: - url: / (stats | login) script: main.py login: required - url:. * script: main.py
/stats , /login and “everything else”. All three, which is typical, will be processed by the same main.py script, but the settings are different - /stats and /login require an active user session, while for the rest it is not necessary. Let's look at the contents of the main.py script: #! / usr / bin / env python
'' '
$ Id: main.py 4 2010-01-25 12: 14: 48Z sigizmund $
'' '
import controller
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.api import users
def main ():
application = webapp.WSGIApplication ([('/', controller.DefaultRequestHandler),
('/ stats', controller.StatsRequestController),
('/ login', controller.LoginController)],
debug = True)
util.run_wsgi_app (application)
if __name__ == '__main__':
main ()
controllers and create the webapp.WSGIApplication instance that matches the request URLs and the corresponding handlers. As a rule, it is convenient to put these handlers in a separate package in order to separate the service code from the real code, which, in fact, determines the behavior of the application. Consider these handlers in turn. class DefaultRequestHandler (webapp.RequestHandler):
'' '
Handles default requests - checks if user is logged in; if it is - saves an information about
his visit in the database.
'' '
def get (self):
user = users.get_current_user ()
page = None
if not user:
page = view.StartPage (self.request)
else:
page = view.WelcomePage (self.request)
page.render (self.response.out)
MainHandler code in the first part , except that it does not generate the page content on its own, but uses some auxiliary classes. At this stage, we will not consider what they are doing - it’s enough for us to know that they generate HTML that meets our requirements - that is, it offers to log in users who have not done so and welcome those who have successfully coped with it.
/login page, the user will redirect to it automatically and also automatically redirected further to the page / . What happens on this page? For this we need to consider two classes at once. class LoggedInRequestHandler (webapp.RequestHandler):
def currentVisitor (self):
user = users.get_current_user ()
# we shouldn't check user, as / login and / stats specifies
# login: required in app.yaml
q = model.Visitor.all ()
q.filter ('user =', user)
qr = q.fetch (2)
if len (qr) == 0:
u = model.Visitor ()
elif len (qr)> 1:
# something is horribly wrong here, it shouldn't happen
# but it still could
logging.error ("Duplicating user% s in datastore"% user.nickname ())
raise Exception ("Duplicating user% s in datastore"% user.nickname ())
else:
u = qr [0]
self.currentVisitor = u
return u
webapp.RequestHandler . As you can see, the described class does not define the get method — that is, as an independent developer, it will be rather useless. All it does is provide the currentVisitor() method, which either gets from the Datastore or creates a new Visitor instance and returns it. Consider this code in more detail.filter() and ancestor() . The example is very simple, but it shows almost everything you need to extract the necessary entry from the Datastore; Of course, in real applications, this query will probably be much more complicated. class LoginController (LoggedInRequestHandler):
'' '
We use this controller for the login event.
'' '
def get (self):
u = self.currentVisitor ()
u.hits = u.hits + 1
u.put ()
self.redirect ('/')
/login marked as requiring a mandatory login (that is, if the user tries to log in without authentication, he will be automatically redirected to the login page). class StatsRequestController (LoggedInRequestHandler):
def get (self):
u = self.currentVisitor ()
page = view.StatsPage (self.request, u)
page.render (self.response.out)
Source: https://habr.com/ru/post/81933/
All Articles