2016-02-08 1 views
0

У меня возникли проблемы с созданием страниц admin на моем сайте Python Google App Engine. Я думаю, что ответ должен быть довольно простым, но, честно говоря, я пытался понять, как классы наследуются от других классов или использовать функции для переноса других функций, и я просто не могу понять, насколько это хорошо.Создание ограниченных страниц в движке 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, включенную во всех других обработчиках, которые охватывают «административные» задачи.

Обновление: Брент Уошберн указал мне в правильном направлении, чтобы заставить работу работать, хотя я все еще не чувствую, что я понимаю, что на самом деле делает функция декоратора. Во всяком случае, код, кажется, работает, и теперь выглядит следующим образом:

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') 

И так далее для всех остальных «администратор» обработчиков.

+0

Я не уверен, что вы спрашиваете здесь. Не работает ли этот код? Что происходит, когда вы его используете? –

+0

Как написано ** ** только ** проверяет статус администратора на странице AdminHandler. Я хочу, чтобы он проверял статус администратора на всех страницах Admin (Admin, Add, Delete, Reorder), но я думаю, что делаю ошибку, если я непосредственно дублирую логику в AdminHandler. Я чувствую, что некоторые обработчики могут «наследовать» это от AdminHandler, или что я могу обернуть их GET и POST в какой-то другой функции. Но я не уверен, как это сделать. – wbruntra

+0

Но эти классы * do * наследуют от BaseHander, и вы * do * переопределяете метод обёртки (отправки), поэтому я не могу понять, что не работает. –

ответ

0

Вот перебором способ обеспечить пользователь авторизован для каждой страницы (кроме страницы входа в систему), или перенаправляет их на страницу входа в систему:

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') 

Лучший способ это добавить этот код в верхней части каждой получить() и положить() рутина:

def get(self): 
    if not self.session['username']: 
     return redirect('/login') 

еще лучше способ превратить этот код в декоратор так все, что вам нужно добавить это одна строка:

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

Это выглядит многообещающе, но как превратить его в декоратор? Куда идет эта функция? Под BaseHandler? – wbruntra

+1

Возможно, это поможет: http://stackoverflow.com/q/20945366/584846 –

+0

Спасибо. Вопрос обновлен, чтобы включить мою попытку реализовать ваше решение. – wbruntra

Смежные вопросы