Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在google应用程序引擎中创建受限页面_Python_Google App Engine_Webapp2 - Fatal编程技术网

Python 在google应用程序引擎中创建受限页面

Python 在google应用程序引擎中创建受限页面,python,google-app-engine,webapp2,Python,Google App Engine,Webapp2,在我的Python Google应用程序引擎站点上创建管理员页面时遇到问题。我认为答案应该很简单,但老实说,我一直在试图理解类是如何从其他类继承的,或是如何使用函数包装其他函数的,而我似乎对此没有很好的理解 基本上,我的站点有两种页面:主页,然后是一些允许用户执行管理操作的页面。任何人无需登录即可查看主页。其他页面是管理员的。唯一拥有帐户的用户是管理员,因此我设置了webapp2会话,只要 self.sessions.get('username') 返回足以允许访问其他页面的内容 以下是我的处

在我的Python Google应用程序引擎站点上创建管理员页面时遇到问题。我认为答案应该很简单,但老实说,我一直在试图理解类是如何从其他类继承的,或是如何使用函数包装其他函数的,而我似乎对此没有很好的理解

基本上,我的站点有两种页面:主页,然后是一些允许用户执行管理操作的页面。任何人无需登录即可查看主页。其他页面是管理员的。唯一拥有帐户的用户是管理员,因此我设置了webapp2会话,只要

self.sessions.get('username')
返回足以允许访问其他页面的内容

以下是我的处理程序:

class BaseHandler(webapp2.RequestHandler):
    def write(self, *a, **kw):
        self.response.out.write(*a, **kw)

    def render(self, template, **kw):
        self.response.out.write(render_str(template, **kw))

    def dispatch(self):
        # Get a session store for this request.
        self.session_store = sessions.get_store(request=self.request)

        try:
            # Dispatch the request.
            webapp2.RequestHandler.dispatch(self)
        finally:
            # Save all sessions.
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def session(self):
        # Returns a session using the default cookie key.
        return self.session_store.get_session()

class MainHandler(BaseHandler):
    def get(self):
        animals = Animal.query().fetch(100)
        self.render('index.html',animals=animals)

class AdminHandler(BaseHandler):
    def get(self):
        if self.session.get('username'):
            self.render('admin.html')
        else:
            self.render('signin.html')

class ReorderHandler(BaseHandler):
    def get(self):
        self.render('reorder.html')
    def post(self):
        #Change order of item display
        self.write('OK')

class DeleteHandler(BaseHandler):
    def get(self):
        self.render('delete.html')
    def post(self):
        #Delete entry from db
        self.write('OK')

class AddHandler(BaseHandler):
    def get(self):
        self.render('add.html')
    def post(self):
        #add entry to db
        self.write('OK')

class SigninHandler(BaseHandler):
    def post(self):
        #Check username and password
        if valid:
            self.session['username'] = username
            self.redirect('/admin')
        else:
            self.write('Not valid')
AdminHandler列出了这些管理页面应该做什么的基本逻辑。 如果有人试图访问管理页面,处理程序应该检查用户是否已登录,如果是,则允许访问该页面。如果不是,则呈现登录页面

重新排序、删除和添加都是我希望管理员能够执行的操作,但将来可能会有更多操作。我可以将AdminHandler逻辑添加到其他处理程序的所有get和post中,但这是非常重复的,因此我确信这样做是错误的

寻找有关如何将AdminHandler的逻辑合并到所有其他包含“管理”任务的处理程序中的一些指导

更新:Brent Washburne为我指出了正确的方向,足以让事情正常运行,尽管我仍然不理解decorator函数的实际功能。无论如何,代码似乎正在运行,现在看起来如下:

def require_user(old_func):
    def new_function(self):
        if not self.session.get('username'):
            self.redirect('/signin')
        old_func(self)
    return new_function

class AdminHandler(BaseHandler):
    @require_user
    def get(self):
        self.render('admin.html')

class AddHandler(BaseHandler):
    @require_user
    def get(self):
        self.render('add.html')
    @require_user
    def post(self):
        name = self.request.get('name')
        qry = Animal.query(Animal.name == name).get()
        if not qry:
            new_animal = Animal(name=name)
            new_animal.put()
        self.write('OK')

依此类推所有其他“管理员”处理程序。

这里有一种强力方法,可以确保用户在每个页面(登录页面除外)都登录,或者将用户重定向到登录页面:

def dispatch(self):
    # Get a session store for this request.
    self.session_store = sessions.get_store(request=self.request)

    if not self.session['username'] and self.request.get('path') != '/login':
        return redirect('/login')
更好的方法是将此代码添加到每个get()和put()例程的顶部:

更好的方法是将代码转换为装饰器,这样您只需添加一行代码:

@require_login
def get(self):
    ....

我不知道你在问什么。这个代码不起作用吗?当您使用它时会发生什么?它只检查AdminHandler页面上的管理员状态。我想让它检查所有管理页面(admin、Add、Delete、Reorder)上的管理状态,但是如果我直接复制AdminHandler中的逻辑,我认为我犯了一个错误。我觉得其他处理程序可以从AdminHandler“继承”它,或者我可以将它们的get和post包装到其他函数中。但是我不知道怎么做。但是这些类确实是从BaseHander继承的,并且您确实重写了包装器方法(dispatch),所以我不明白什么不起作用。显然,我对某些事情感到困惑。在我看来,尝试访问“/admin”的人将被检查管理员状态,但尝试获取或发布到“/add”、“/delete”或“/reorder”的人将被允许在不进行任何状态检查的情况下执行此操作。这是您正在寻找的吗?对于任何需要登录用户的路由,它都会使用decorator,而无需每次重复代码。这看起来很有希望,但如何将其转化为decorator呢?这个函数去哪里了?在BaseHandler下面?谢谢。问题已更新,包括我尝试实施您的解决方案。
@require_login
def get(self):
    ....