dev_appserver.py .터미널 윈도우에 애플리케이션을 띄워놓으면 소스코드를 변경했을 때 그 내용이 자동으로 반영된다. 각자가 선호하는 에디터로 change.py를 다른 창으로 열어보면, 이 파일이 애플리케이션의 대부분을 차지함을 알 수 있다. 이 파일의 코드는 다음과 같다.
#!/usr/bin/env python2.5 #Noah Gift import decimal import wsgiref.handlers import os from google.appengine.api import users from google.appengine.ext import webapp from google.appengine.ext import db from google.appengine.ext.webapp import template class ChangeModel(db.Model): user = db.UserProperty() input = db.IntegerProperty() date = db.DateTimeProperty(auto_now_add=True) class MainPage(webapp.RequestHandler): """Main Page View""" def get(self): user = users.get_current_user() if users.get_current_user(): url = users.create_logout_url(self.request.uri) url_linktext = "Logout" else: url = users.create_login_url(self.request.uri) url_linktext = "Login" template_values = { "url": url, "url_linktext": url_linktext, } path = os.path.join(os.path.dirname(__file__), "index.html") self.response.out.write(template.render(path, template_values)) class Recent(webapp.RequestHandler): """Query Last 10 Requests""" def get(self): #collection collection = [] #grab last 10 records from datastore query = ChangeModel.all().order("-date") records = query.fetch(limit=10) #formats decimal correctly for change in records: collection.append(decimal.Decimal(change.input)/100) template_values = { "inputs": collection, "records": records, } path = os.path.join(os.path.dirname(__file__), "query.html") self.response.out.write(template.render(path,template_values)) class Result(webapp.RequestHandler): """Returns Page with Results""" def __init__(self): self.coins = [1,5,10,25] self.coin_lookup = {25: "quarters", 10: "dimes", 5: "nickels", 1: "pennies"} def get(self): #Just grab the latest post collection = {} #select the latest input from the datastore change = db.GqlQuery("SELECT * FROM ChangeModel ORDER BY date DESC LIMIT 1") for c in change: change_input = c.input #coin change logic coin = self.coins.pop() num, rem = divmod(change_input, coin) if num: collection[self.coin_lookup[coin]] = num while rem > 0: coin = self.coins.pop() num, rem = divmod(rem, coin) if num: collection[self.coin_lookup[coin]] = num template_values = { "collection": collection, "input": decimal.Decimal(change_input)/100, } #render template path = os.path.join(os.path.dirname(__file__), "result.html") self.response.out.write(template.render(path, template_values)) class Change(webapp.RequestHandler): def post(self): """Printing Method For Recursive Results and While Results""" model = ChangeModel() try: change_input = decimal.Decimal(self.request.get("content")) model.input = int(change_input*100) model.put() self.redirect("/result") except decimal.InvalidOperation: path = os.path.join(os.path.dirname(__file__), "submit_error.html") self.response.out.write(template.render(path,None)) def main(): application = webapp.WSGIApplication([("/", MainPage), ("/submit_form", Change), ("/result", Result), ("/recent", Recent)], debug=True) wsgiref.handlers.CGIHandler().run(application) if __name__ == "__main__": main()실용적인 면을 강조하는 튜토리얼답게, 우선 http://greedycoin.appspot.com이나 로컬에서 돌아가는 http://localhost:8080/를 살펴보는 것으로 시작해보자. 호박 색으로 뒤덮인 두 개의 플로팅(floating) 박스가 있는데, 왼쪽은 교환하고자 하는 돈의 액수를 넣는 곳이고, 오른쪽은 메뉴 박스이다. 화려할 수도 이상하게도 보일 수 있는 색과 레이아웃은 장고 템플릿과 CSS를 단순히 조합하여 만들어졌다. 장고 템플릿은 메인 디렉토리에, CSS 파일은 스타일시트에 위치해있다. 장고 템플릿은 GAE와는 상관이 없기 때문에, 이에 대해 잘 알지 못한다면 참고자료에 있는 장고 템플릿 링크를 따라가보기 바란다.
class MainPage(webapp.RequestHandler): """Main Page View""" def get(self): user = users.get_current_user() if users.get_current_user(): url = users.create_logout_url(self.request.uri) url_linktext = "Logout" else: url = users.create_login_url(self.request.uri) url_linktext = "Login" template_values = { "url": url, "url_linktext": url_linktext, } path = os.path.join(os.path.dirname(__file__), "index.html") self.response.out.write(template.render(path, template_values))Mainpage 클래스는 webapp.RequestHandler를 상속받았으며, get 메소드를 정의하면 사용자의 로그인 여부를 판단할 수 있는 페이지를 만들 수가 있다. 인증 부분 아래를 보면 알겠지만, 템플릿 시스템으로 넘어간 사용자 정보는 장고 템플릿을 통해 index.html로 렌더링된다. 한 가지 놀라운 사실은 페이지 인증을 거치기 위해 구글 유저 계정 데이터베이스를 이용한다 것이 너무나도 쉽다는 점이다. 바로 다음과 같이 말이다.
user = users.get_current_user() if users.get_current_user():이 코드로 이것저것 시도해보면서 인증된 사용자에게만 적용될 수 있는 코드를 추가해보도록 하자. 지금 당장 코드가 어떻게 돌아가는지 이해할 필요는 없고, 기존의 조건문을 활용해서 추가작업을 해보자.
최신 콘텐츠