Model-View-Controller

A web application is generally separated into three parts:
  • Model-- server code that handles data and database information
  • View--  code that displays data (HTML, CSS, and templates)
  • Controller-- server code that responds to user interaction, communicates with the model, and updates the view.

Model

Model code is written in some high-level programming language such as Java, Python, or C++. Usually the model code interfaces with a database using the Standard Query Language (SQL). In these lessons, we'll be using Python and the high-level "DataStore" API that Google provides. The DataStore library hides some of the details of database processing, but we'll still learn something about it, including some SQL (notes on persistent data)

View

For a web application, the 'view' consists of HTML templates and CSS styling files. The HTML specifies the components that appear on a web page. CSS specifies the styling of those pages, e.g., the background color.

Web page templates are something like form letters for the web. A template is HTML except for the dynamic part of the page-- the part which displays live data from a database or computation. Templates use special syntax for this variable part of the page. Controller code sets up the values that replace the variables. A template engine is the software that replaces the variables with specific data from the controller.

template --> template Engine --> generated HTML sent to browser

In these lessons, we'll be using a version of Django templates used in Google's Appengine samples.

Here's an HTML template  for a simple interest calculator (see this tutorial for code of entire application):


<html>
  <body>
    <h2>Interest Calculator</h2>   
    <h3>Enter the principal and interest rate</h3>

    <form action="/on_calculate" method="get">
      Principal:<input type="text" name="principal" value={{principal}}>
      Rate(%):<input type="text" name="rate" value={{rate}}>
      <input type="submit" value="Calculate"></div>
    </form>

    Interest Earned: {{interest}}
   
  </body>
</html>


The dynamic parts of the page-- the parts that can appear differently each time the page is rendered, are in double curly brackets. In this case,  the {{principal}}, {{rate}}, and {{interest}} will be replace by values computed by the server code.

Templates also provide syntax for displaying lists and incorporating more complex code. These are sometimes called template tags, and in Django, this code is enclosed in {%   %}. We'll discuss this later.


Controller

The controller is server code that gets invoked when 1) a user enters a URL in a browser, 2) a user clicks on a link, and 3) the user interacts enters data and submits a form, as in the samples above.

In the first two cases, the request sent to the server is essentially everything in the URL other than the domain name.

URL                                                                    REQUEST SENT TO mysite.com server
mysite.com                                                        /
mysite.com/hello?p1=55                                   hello?p1=55
mysite.com/schools/getData?name=45            getData?name=45

With a form the request sent is the action along with parameters for any elements defined within the form. Consider the interest rate example above. If the user entered 1000 and 10 for the principal and rate, the request sent to the server would be:

/on_calculate?principal=1000&rate=10

Controller code does the following:
  • reacts to end-user actions
  • interacts with the model to get data and perform computations on it.
  • replaces the template variables with specific values and renders dynamic pages.
Before continuing, go through this worksheet on view-controller mappings.

We'll write our controller code in Python. One thing your Python controller code will do is specify the class that should handle each request. In the code below, we specify that a class called 'MainPage' should handle the home request (/), and a class named 'CalcController' should handle the 'on_calculate' request.

 
    application = webapp.WSGIApplication(
                  
                                     [('/', MainPage),
                
                                      ('/on_calculate, CalcController)],
                                     debug=True)


Code like this is put in the main program section of your controller. You can specify as many mappings as you want to handle various requests. In general, you'll have a mapping for each page on your site, and for each form on those pages.

The classes that handle requests are subclasses of webapp.RequestHandler. Their job is to:
  • process parameters
  • perform computations and access database
  • set the template values and invoke the new page.
Here's the controller classes used in the interest rate program:

class MainPage(webapp.RequestHandler):
  def get(self):
    template_values={'principal':'1000','rate':'10'}
    # render the page using the template engine
    path = os.path.join(os.path.dirname(__file__),'index.html')
    self.response.out.write(template.render(path,template_values))

class CalcController(webapp.RequestHandler):
  def get(self):
    principalString=self.request.get('principal')
    rateString = self.request.get('rate')
    principal = int(principalString)
    rate = int(rateString)
    interest = principal*rate/100
    interestString = str(interest)
   # set up the template_values with the list of people returned.
    template_values= {'interest':interestString, 'principal':principalString,'rate':rateString}
    # render the page using the template engine
    path = os.path.join(os.path.dirname(__file__),'index.html')
    self.response.out.write(template.render(path,template_values))

The first class, MainPage, specifies how the server responds to the user invoking the main page. In this case, there are no parameters. We just:
  • set default values for the 'principal' and 'rate' in template_values. These names correspond to the names in the HTML template form.
  • render index.html (our template) which generates the HTML sent to the browser.
The second class, CalcController, does the following:
  • grabs the parameters principal, and rate from the request. This is what the end-user has entered into the form.
  • converts those numbers into integers.
  • computes the interest.
  • Sets the computed interest and the input numbers  into the template_values.
  • renders index.html again.

Interfacing with the Model

For many examples, such as with a social network, the controller will also interface with the model using Google's DataStore API. Here's an example:

    people=db.GqlQuery("SELECT * FROM Person")    # get data from model

This code queries the database for a list of all persons in the Person table.

Here's the entire controller code for when the initial page is loaded in the sample PersonBook:

# main page appears on load
class MainPage(webapp.RequestHandler):
  def get(self):
   # get all the persons in the database
    people=db.GqlQuery("SELECT * FROM Person")
   # set up the template_values with the list of people returned.
    template_values= {'people':people}
    # render the page using the template engine
    path = os.path.join(os.path.dirname(__file__),'index.html')
    self.response.out.write(template.render(path,template_values))


We'll explore such code in-depth in future lessons.

Recent site activity