[Google App Engine]Django를 이용한 Google App Engine 개발 -2-

2012, Oct 15    

1. 시작하기 전에...

 이번 포스팅은 Django를 이용한 Google App Engine 개발 -1-를 이어 이야기를 진행하도록 하겠습니다.

 저번 포스팅에는 Google App Engine에서 Django가 구동되는것 까지만 확인까지 하였는데 그 뒤에 개발에 실직적으로 필요한 부분을 다루도록 하겠습니다.

2. Django MVT 흐름 이해하기

 보통 웹 프레임워크에서는 MVC 패턴(Model-View-Controller)이라 하는데 Django는 MVT(Model-View-Template)라고 합니다. Django에서 View를 MVC패턴에서의 Controller 역활을 그리고 Template은 MVC패턴에서의 View 역활을 합니다.

 말 장난 같아 보이는데 똑같은 역활을 하는게 이름이 다를 뿐이라고 생각을 하시면 됩니다.^^ 인제 본격적으로 흐름에 대해서 알아보겠습니다.   

 클라이언트(사용자)에서 웹서버 쪽으로 요청이 들어오면 요청된 URL으로 제어가 됩니다 그 부분은 urls.py에 정의할 수 있습니다.

from django.conf.urls import patterns, url, include

urlpatterns = patterns('',
    (r'^articles/2003/$', 'news.views.special_case_2003'),
    (r'^articles/(\d{4})/$', 'news.views.year_archive'),
    (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
    (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)

 위의 내용은 urls.py의 예제입니다.

 정규표현식으로  url를 걸러 널러 낼수 있으며 정규표현식에 적합한 요청은 다음의 view(MVC패턴에서 Controller 역활)로 넘어 가게 됩니다. django같은 경우 Elegant URL design이라 불리우는 URL를 줄여주는 기능이 있습니다. GET 요청의 파라미터 역활 대신에 정규표현식을 통해 URL PATH에서 특정 요청정보를 가져 올 수 있습니다.  

  (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive')

를 예를 들자면 이 있습니다. ^articles/(?P<year>\d{4})/$에 해당되는 PATH가 요청이 되면 news.views.year_archive뷰로 넘어가게 됩니다. 이때 year의 변수에 4자리 수의 수가 같이 넘겨 줄 수 있습니다. 넘어오는 변수를 잘 사용하여 동적인 페이지를 만들 수 있습니다.

 

 인제 Controller 역활을 하는 View를 살펴보겠습니다.

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
 

 위의 코드는 심플한 View의 코드소스입니다. 이 코드는 Template를 쓰지 않고 파이썬 코드 상에서 HTML코드를 생성합니다.

리턴타입이 HttpResponse입니다. 이 서브 클래스가 다양하게 존재하는데 리다이렉트를 할 경우나 여러 상황에 맞게 사용할 수 있습니다.

 

다음은 Template에 대해 알아 보겠습니다.

>>> from django.template import Context, Template
>>> t = Template("My name is {{ my_name }}.")

>>> c = Context({"my_name": "Adrian"})
>>> t.render(c)
"My name is Adrian."

>>> c = Context({"my_name": "Dolores"})
>>> t.render(c)
"My name is Dolores."

 가장 기본적인 코드입니다. 문장안에 {{ }}"에 들어간 변수를 값으로 치환해주는 방식입니다.

변수 치환뿐만 아니라 if문, for문 같은 기본적인 문법을 지원해서 변수를 살짝 제어해서 결과물을 다르게 나올게 할 수 있습니다.

실제 코드에서는 보통 아래와 같이 쓰입니다.

def some_view(request):
    # ...
    return render_to_response('my_template.html',
                              my_data_dictionary)

 템플릿을 HTML파일로 만들고 넘겨줄 변수의 집합은 dictionary자료형을 두번째 인자로 render_to_response함수를 불러서 사용합니다.

3. Datastore 이해하기.

 Datastore는 스키마가 없는 데이터베이스입니다. 즉 NoSQL입니다. 

import datetime
from google.appengine.ext import db
from google.appengine.api import users
class Employee(db.Model):
  name = db.StringProperty(required=True)
  role = db.StringProperty(required=True,
                           choices=set(["executive", "manager", "producer"]))
  hire_date = db.DateProperty()
  new_hire_training_completed = db.BooleanProperty(indexed=False)
  email = db.StringProperty()
e = Employee(name="John",
             role="manager",
             email=users.get_current_user().email())
e.hire_date = datetime.datetime.now().date()

 Datastore는 스키마가 없는 데이터베이스라고 했지만 스키마처럼 역활을 하는 클래스가 필요합니다. 클래스 안에서 각 필드에 대한 자료형을 정의 합니다. 그리고 객체를 생성한 후 데이터를 변경을 하고 put()이라는 함수를 이용하여 추가및 수정을 할 수 있습니다.

 수정 같은 경우에는 각 객체마다 키가 존재하는데 그 키로 검색하거나 해서 한 객체를 얻은후 수정 후 put()함수를 쓰면 수정이 됩니다.

NoSQL같은 경우 sql처럼 join이 없기 때문에 설계를 잘 하셔야 됩니다.

4. Users API

 Django같은 경우 Session을 Database를 이용해서 Session처리를 하는 프레임워크입니다. 하지만 Django를 Google App Engine과 같이 쓰면서 기존의 Django의 데이터베이스를 쓰는 방법을 쓰지 않고 Datastore를 이용해서 데이터베이스를 쓰기 때문에 Session를 사용할 수 없습니다. (Datastore 대신Google Cloud SQL를 쓰면 Session이 사용가능합니다.)

 하지만 걱정할 필요가 없습니다. Users Api를 제공하고 있습니다. google계정으로 로그인이 가능하며 세션유지도 됩니다. 

from google.appengine.api import users

def loginView(request):
   user = users.get_current_user()
   if user:
      greeting = ("Welcome, %s! (<a href=\"%s\">sign out</a>)" %
                   (user.nickname(), users.create_logout_url("/")))
   else:
      greeting = ("<a href=\"%s\">Sign in or register</a>." %
                  users.create_login_url("/"))
   return HttpResponse(greeting)

위의 코드를 실행 시켜보면 다음과 같이 화면이 나옵니다.

버튼을 눌러보면 구글계정으로 로그인하게 되어있습니다.
가입을 하고 나서 로그인을 하게 되면 다음과 같이 나옵니다.

users 객체에 email이나 nickname, user_id 몇가지 정보를 가지고 있습니다. 이 정보로는 회원관리가 힘들시다면 user_id를 저장하고 기타정보를 담고 있는 것을 Datastore를 이용하여 만들어 관리 할 수 있습니다.

요즘 개인정보보호때문에 개인정보를 Database에 가지고 있는게 부담스러운 현실인데 이런 방법이면 별로 신경안써도 되겠죠?

 

5. Mail API

 보통 웹서비스를 할때 메일을 사용할려면 STMP서버를 구성하거나 메일호스팅서비스를 받거나 해야 됩니다. 하지만 Google App Engine에서는 따로 구축하거나 할 필요가 없습니다.

from google.appengine.api import mail
from django.http import HttpResponse
                                                                                    
def sendMail(req):
  message = mail.EmailMessage(sender="kpdc.org Support <rucifer1217@gmail.com>",
                              subject="가입을 축하드립니다.")
            
  message.to = "rucifer <rucifer1217@gmail.com>"
  message.body= """  
  kpdc.org 가입을 축하드립니다."""
  message.send()
  html="<html><body>successfully sent mail.</body></html>"
  return HttpResponse(html)

</p>

 코드는 따로 설명할 것이 없을 만큼 간단합니다. mail.EmailMessage으로 객체를 하나 생성하고 그 객체의 변수에 알맞은 값을 넣어 주면 됩니다.

 하지만 따로 설정해야되는게 있다면 메일을 보내는 사람의 메일주소입니다. 이 메일은 Google App Engine의 Admninistration Consol의 Administration의 하위메뉴인 Permissions에서 위와 같이 보내는 사람의 주소가 등록이 되어야하며 Role은 Developer이상이 되어야 메일이 발송이 됩니다. 위의 코드를 실행시켜보면 

위와 같이 성공했다는 페이지가 나오며 

 위와 같이 페이지가 나오며 아래와 같이 메일이 온 것을 확인 할 수 있습니다. 메일 발송을 통해서 회원가입 축하 메일이라든지 메일인증, 비밀번호찾기 등의 기능을 만들 수 있으며 주기적으로 웹사이트 상태를 로그로 관리자에게 보내는 등의 응용 할 수 있는 부분이 많이 있을 것 같습니다.

참고사이트 : https://docs.djangoproject.com, https://developers.google.com/appengine