More Related Content Similar to Gae Meets Django (20) Gae Meets Django4. Google App Engine
• Google Web Hosting
• Web Google
• Scaling load balancing
•
• Google User Gmail
5. • Python 2.5.2
• Django 0.96.1 CGI
CGI WSGI
• Sandbox
socket cron job
• response
• Python C
6. Datastore
• Google BigTable
• ORM
• Model
•
• join, sum, avg
• 1000
•
8. ( )
Fixed Quota Per Day Usage Quotas
500 PV/
9. • $0.10 - $0.12 per CPU core-hour
• $0.15 - $0.18 per GB-month of storage
• $0.11 - $0.13 per GB outgoing bandwidth
• $0.09 - $0.11 per GB incoming bandwidth
10. Google App Engine
• http://appengine.google.com/
• Gmail
•
• : http://yourapp.appspot.com
• Google Apps
11. • Web
• idea, startup
• scalability
• App Gallery http://appgallery.appspot.com/
14. Django
• Python full-stack Web
• ORM, URL mapping, admin interface,
template, middleware, i18n, cache...
•
15. Django webapp
• Google App Engine Helper for Django
•
•
17. • Google App Engine SDK
http://code.google.com/appengine/downloads.html
• SVN Django
http://code.djangoproject.com/svn/django/trunk/
• Google App Engine Helper for Django
http://code.google.com/p/google-app-engine-django/
18. --- appengine-django (app engine helper for django )
--- django (django )
--- onlypy ( )
--- static ( js, css, )
--- app.yaml (app engine )
--- index.yaml (app engine )
--- main.py (app engine )
--- manage.py (Django )
--- settings.py ( )
--- urls.py (URL mapping)
19. app.yaml
application:
onlypython
version:
1
runtime:
python
api_version:
1
handlers:
-‐
url:
/static
static_dir:
static
-‐
url:
/.*
script:
main.py
20. main.py
import
os
import
sys
import
logging
from
appengine_django
import
InstallAppengineHelperForDjango
InstallAppengineHelperForDjango()
#
Google
App
Engine
imports.
from
google.appengine.ext.webapp
import
util
#
Import
the
part
of
Django
that
we
use
here.
import
django.core.handlers.wsgi
def
main():
#
Create
a
Django
application
for
WSGI.
application
=
django.core.handlers.wsgi.WSGIHandler()
#
Run
the
WSGI
CGI
handler
with
that
application.
util.run_wsgi_app(application)
if
__name__
==
'__main__':
main()
21. settings.py
TIME_ZONE
=
'UTC'
MIDDLEWARE_CLASSES
=
(
'django.middleware.common.CommonMiddleware',
'appengine_django.auth.middleware.AuthenticationMiddleware',
)
ROOT_URLCONF
=
'urls'
ROOT_PATH
=
os.path.dirname(__file__)
TEMPLATE_DIRS
=
(
os.path.join(ROOT_PATH,
'onlypy/templates')
)
INSTALLED_APPS
=
(
'appengine_django',
'django.contrib.auth',
'onlypy.blog',
)
23. models.py
from
google.appengine.ext
import
db
class
Category(db.Model):
name
=
db.StringProperty()
def
__str__(self):
return
self.name
class
Post(db.Model):
author
=
db.UserProperty()
title
=
db.StringProperty(required=True,
verbose_name=u' ')
tag
=
db.StringProperty(verbose_name=u' ')
content
=
db.TextProperty(required=True,
verbose_name=u' ')
create_time
=
db.DateTimeProperty(auto_now_add=True)
update_time
=
db.DateTimeProperty(auto_now=True)
category
=
db.ReferenceProperty(Category,
required=True,
verbose_name=u' ')
is_published
=
db.BooleanProperty(verbose_name=u' ')
def
get_absolute_url(self)
:
return
'/post/%s/'%self.key().id()
25. views.py
def
add_post(request):
if
request.method
==
'GET':
form
=
PostForm()
if
request.method
==
'POST':
form
=
PostForm(request.POST)
if
form.is_valid():
post
=
form.save()
post.author
=
users.get_current_user()
post.put()
return
HttpResponseRedirect('/post/add/')
return
render_to_response('blog/add_post.html',
{'form':
form},
context_instance=RequestContext(request))
26. add_post.html
{%
extends
"base.html"
%}
{%
block
content
%}
<h1> </h1>
<form
name="mainForm"
method="post"
action="">
{{form.as_p}}
<input
type="submit"
value=" "/>
</form>
{%
endblock
%}
31. views.py
def
list_post(request):
posts
=
Post.all().order('-‐create_time')
if
(not
is_admin()):
posts
=
posts.filter("is_published",
True)
return
object_list(request,
queryset=posts,
allow_empty=True,
template_name='blog/list_post.html',
extra_context={'is_admin':
is_admin()},
paginate_by=20)
32. index.yaml
indexes:
-‐
kind:
Post
properties:
-‐
name:
is_published
-‐
name:
create_time
direction:
desc
33. list_post.html
{%
extends
"base.html"
%}
{%
load
markup
%}
{%
load
paginator
%}
{%
block
content
%}
{%
for
post
in
object_list
%}
<table
border="0"
cellspacing="0"
cellpadding="0"
width="100%">
<tr>
<td
valign="top">
<h1
style="margin-‐bottom:
2px;">
<a
href="/post/{{post.key.id}}">
[{{
post.category.name
}}]
{{
post.title
}}{%
if
post.is_published
%}
{%else%}( ){%endif%}
</a>
</h1>
<p
style="padding:0px;
margin:
0px;"
class="small_font">
:
<a
href="/category/{{
post.category.key.id
}}/">
{{
post.category.name
}}</a>
<span
style="padding-‐left:
10px;">{{
post.author.nickname
}}
{{
post.create_time|date:"Y-‐M-‐d
H:i"
}}</span>
</p>
</td>
</tr>
</table>
<div
style="padding-‐left:
30px;">
{{
post.content|markdown
}}
</div>
{%
endfor
%}
{%
paginator
%}
{%
endblock
%}
36. • http://code.google.com/p/onlypy/
• http://www.onlypython.com