App Engine MVC

I just scratched an itch to break out the App Engine Guestbook Tutorial into what satisfies me as a simple MVC framework (file/directory structure). The main benefit is to do data hiding on the model and controller (handler) classes to get them into different modules and so improve readability for me.

Small Changes

  • Figuring out the imports was a bit tricky.
    There may be a better way but this worked.
    GuestbookM.py (the Guestbook Module) contains the class Guestbook, etc..
  • In class MainPage
    NOW:
    path = os.path.join(os.path.dirname(file), ‘../v/templates/MainPage.html’)
    WAS:
    path = os.path.join(os.path.dirname(file), ‘index.html’)

  • I used the guestbook6_templates.py version available here. The index.html file is now in MainPage.html. The app name is jmvc. Here is the file structure:

jmvc/
    c/
        __init__.py
        GuestbookM.py
        MainPageM.py
    m/
        __init__.py
        GreetingM.py
    v/
        stylesheets/
            main.css
        templates/
            MainPage.html
            __init__.py
    app.yaml
    main.py

All init.py files are blank. As I said before MainPage.html is the same as index.html in the non MVC code. Here is the source for each of the remaining files :

# app.yaml

application: jmvc
version: 1
runtime: python
api_version: 1

handlers:

- url: /v/stylesheets
static_dir: v/stylesheets

- url: /.*
script: main.py

# main.py

import cgi
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

from c import MainPageM
MainPage = MainPageM.MainPage

from c import Guestbook
Guestbook = GuestbookM.Guestbook

application = webapp.WSGIApplication(
    [('/', MainPage),
    ('/sign', Guestbook)],
    debug=True)
def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

# GuestbookM.py

from google.appengine.ext import webapp
from google.appengine.api import users

from m import GreetingM
Greeting = GreetingM.Greeting

class Guestbook(webapp.RequestHandler):
def post(self):
    greeting = Greeting()

    if users.get_current_user():
        greeting.author = users.get_current_user()

    greeting.content = self.request.get('content')
    greeting.put()
    self.redirect('/')


#MainPage.py


from google.appengine.ext import webapp
from google.appengine.api import users
import os
from google.appengine.ext.webapp import template

from m import GreetingM
Greeting = GreetingM.Greeting


class MainPage(webapp.RequestHandler):
def get(self):
    greetings_query = Greeting.all().order('-date')
    greetings = greetings_query.fetch(10)

    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 = {
    'greetings': greetings,
    'url': url,
    'url_linktext': url_linktext,
}

path = os.path.join(os.path.dirname(__file__), 
    '../v/templates/MainPage.html')
    self.response.out.write(template.render(path, 
    template_values))

# GuestbookM.py

from google.appengine.ext import webapp
from google.appengine.api import users

from m import GreetingM
Greeting = GreetingM.Greeting

class Guestbook(webapp.RequestHandler):
    def post(self):
        greeting = Greeting()

    if users.get_current_user():
        greeting.author = users.get_current_user()
        greeting.content = self.request.get('content')
        greeting.put()
        self.redirect('/')

# MainPage.py


from google.appengine.ext import webapp
from google.appengine.api import users
import os
from google.appengine.ext.webapp import template

from m import GreetingM
Greeting = GreetingM.Greeting


class MainPage(webapp.RequestHandler):
    def get(self):
        greetings_query = Greeting.all().order('-date')
        greetings = greetings_query.fetch(10)

        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 = {
    'greetings': greetings,
    'url': url,
    'url_linktext': url_linktext,
}

path = os.path.join(os.path.dirname(__file__), 
    '../v/templates/MainPage.html')
    self.response.out.write(template.render(path, 
    template_values))


# GreetingM.py


from google.appengine.ext import db
from google.appengine.api import users

class Greeting(db.Model):
    author = db.UserProperty()
    content = db.StringProperty(multiline=True)
    date = db.DateTimeProperty(auto_now_add=True)


# main.css

body {
    font-family: Verdana, Helvetica, sans-serif;
    background-color: #DDDDDD;
}

Please comment.

Thanks.
Love and peace,
Joe 🙂

#google-app-engine, #mvc, #programming