Google-App-Engine-Django Tutorial, Part 3 – Creating the application

Posted: July 18th, 2009 | By | Filed under: Development | Tags: , , , | No Comments »

Edit 2014-01-23: The information on this post is extremely outdated! Please refer to the official App Engine cloudSQL documentation, or this article about using django-nonrel, or search for up to date information.

So we left off having an application skeleton, and a local development server running it. In this post we’d create some (very) basic application and upload it to google app engine. This purpose is only to provide a glimpse and have something working. For actually writing an application I suggest reading the documentation for Python, Django, Google App Engine, and GAE-Django listed before. You may also find the blog post. I can also suggest reading this blog post, which goes into greater depth.

Ok, We’re going to write a slog. What’s a slog you ask? A Sandwich Log, of course. We’re going to fill in what we ate, and then have a big long list of it.

First, if you’re not already there, open a terminal, and cd to the django application directory we created last time.

cd /home/amitay/dev/hellodjango

Adding an application to the site

Applications in Django are modules which can contain Models (more on that later on), Views, Templates, and whatnot. Several applications can be mixed in a single site, so usually the aim is to write applications a small, portable, task oriented packages, that you’d be able to use for several sites and projects.

But, for the purpose of this demo, we’re only going to create one application, and use it in our site.

Using manage.py which you may remember, create an application skeleton:

python2.5 manage.py startapp sandwiches

This will create the application skeleton in sandwiches sub directory.

To use this application by the site, we need to edit its settings.py file to include it in its installed apps. Open settings.py in the site directory, find “INSTALLED_APPS” part, and add ‘sandwiches’ app to it. You should end up with something like

...

INSTALLED_APPS = (
'appengine_django',
'sandwiches',
#    'django.contrib.auth',
#    'django.contrib.contenttypes',
#    'django.contrib.sessions',
#    'django.contrib.sites',

)

...

Model

We’d now create a simple model for our sandwiches. A model is a representation of data, which is persisted on google app engine data store (BigTable), or locally when we use the development server. We define our data structure as a model, and then we can perform different queries and operations on this model. The model we’re about to create is based on the google-app-engine-django BaseModel, and it is kind of a hybrid between Django models, and the GAE model.

To create it, edit sandwiches/models.py to contain the following code:

from appengine_django.models import BaseModel
from google.appengine.ext import db

class Sandwich(BaseModel):
    name = db.StringProperty('Sandwich Name', required=True)
    description = db.StringProperty(required=True)
    date_eaten = db.DateTimeProperty(required=True)

This pretty self explanatory code simply defines a model for a sandwich. A sandwich has the following attributes: name, description, and date eaten.

Views

The application will support 3 operations: Display an “Add Sandwich” form, Validate and save a sandwich filled in that form, and list all sandwiches.
First, let’s define a simple form for adding a sandwich. Create sandwiches/forms.py file, and put this code in it:

import google.appengine.ext.db.djangoforms as forms
import models

class SandwichForm(forms.ModelForm):
    class Meta:
        model = models.Sandwich

This defines a very basic form which relies on the Sandwich model we defined earlier. Notice that we use the forms module from google.appengine.ext.db.djangoforms which is provided by google as their implementation/wrapper for django forms.

With this form at hand, we’re can write the 3 actions we need to support in our application, and also a simple index page. Edit sandwiches/views.py, and put the following code in there:

from django.template.context import RequestContext
from django.shortcuts import render_to_response
from forms import SandwichForm
from models import Sandwich
from django.http import HttpResponseRedirect

def index(request):
    # simply render the index page.
    return render_to_response("index.html", RequestContext(request, {'site':'Sandwichlog'}))

def eat(request):
    # display a form for eating a sandwich
    sandwich_form = SandwichForm()
    return render_to_response("sandwich_eat.html", RequestContext(request, {'sandwich_form':sandwich_form}))

def ate(request):
    # validate and save an eaten sandwich
    sandwich_form = SandwichForm(request.POST)
    if sandwich_form.is_valid():
        sandwich_form.save()
        return HttpResponseRedirect("/sandwiches/list")
    else:
        return render_to_response("sandwich_eat.html", RequestContext(request, {'sandwich_form':sandwich_form}))

def list(request):
    # list all sandwiches
    sandwiches = Sandwich.objects.all()
    return render_to_response("sandwiches_list.html", RequestContext(request, {'sandwiches':sandwiches}))

I won’t go into details here, but each of the functions we defined will be used as a “view”. A django View is simply a functions with gets an http request object (and may also get parameters extracted from the requested url, not in this example though), and returns an HttpResponse. Very commonly (and in all the view functions in this example) a view returns a response rendered by a template given a specific context. In “ate” view, the template receives a SandwichForm instance as part of the context to use in rendering.

Url routing (Front Controller)

To let django use these view functions, we need to configure urls.py to use them. In the site directory edit urls.py, and change the “urlpatterns = …” statement to:

urlpatterns = patterns('',
(r'^sandwiches/', include('sandwiches.urls')),
)

This will tell Django to use urls defined in Sandwiches applications, for requests url starting with “sandwiches”.

Create a new urls.py in Sandwiches, and put the following code in it. This will map urls to the different views we created:

from django.conf.urls.defaults import *

urlpatterns = patterns('',

    (r'^$', 'sandwiches.views.index'),
    (r'^eat', 'sandwiches.views.eat'),
    (r'^ate', 'sandwiches.views.ate'),
    (r'^list', 'sandwiches.views.list'),
)

Templates

We need to create the different templates we’re going to use. We’ll create them in sandwiches/templates directory (create one!). It is possible, and often a good practice, to make the templates part of the site, and not the application, but we won’t mind that now.

base.html:

<html>
 <body>
 Hello, {{user}}! <a href="/sandwiches">Home</a>
 <br><br>
 {% block content%}{% endblock%}

 </body>
</html>

index.html:

{% extends "base.html" %}
{% block content %}
 <h2>Welcome to {{ site}}!</h2>
 <a href="eat"> Eat something</a> or <a href="list">see what you ate</a>.

{% endblock %}

sandwich_eat.html:

{% extends "base.html" %}
{% block content %}
 <h2>Tell us what are you eating:</h2>
 <form action="ate" method="post">
 {{ sandwich_form.as_p }}

 <input type="submit" value="eat">
 </form>
{% endblock %}

sandwiches_list.html:

{% extends "base.html" %}
{% block content %}
 <h2>You've been busy lately eating:</h2>
 {% for sandwich in sandwiches %}
 <li> {{ sandwich.name }} ({{sandwich.description}}) on {{sandwich.date_eaten}}
 {% endfor %}
{% endblock %}

You can see in this templates we can extend a base template with other templates that override only the content. To render the form, we simply call the form context as_p() fucntion, by writing the template expression {{ sandwich_form.as_p }} .

Running and Deploying the site

We have all that’s needed to run the application locally. So back to the terminal, run:

python2.5 manage.py runserver 8009

and browse to http://localhost:8009/sandwiches/ to enjoy the application (be sure to have a good sandwich handy to use it properly).

To Deploy the site to google appengine, edit app.yaml in the site directory and change “application: google-app-engine-django” to use your actual application name, as you registered it in Google App Engine.

And to upload it, simply use:

python2.5 manage.py update

You’d be prompted for you app engine email and password. After that, you can use you GAE dashboard to manage the deployed application, or simply browse to http://yourappname.appspot.com/sandwiches to see it live.

For the time being, if you’re just anxious to share your sandwiches with the word, you can see the deployed application here

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Leave a Reply