GAE Meets Django

1,923 views

Published on

Published in: Technology, News & Politics
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,923
On SlideShare
0
From Embeds
0
Number of Embeds
96
Actions
Shares
0
Downloads
43
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

GAE Meets Django

  1. 1. 使用Django创建 Google App Engine应用 林胜 linsheng.cn@gmail.com
  2. 2. • Google App Engine介绍 • Django介绍 • 代码示例
  3. 3. Google App Engine介绍
  4. 4. 什么是Google App Engine • Google的Web Hosting服务 • 将你的Web应用部署到Google的基础设施之上 • 使你的应用能 自动Scaling和load balancing • 提供数据存储服务 • 集成了Google User认证和Gmail等服务
  5. 5. 运行环境和限制 • Python 2.5.2 • 内置Django 0.96.1,并支持所有支持CGI的框架 (以及任何使用CGI适配器的WSGI框架) • 运行在Sandbox中,不能访问文件系统,不能建 立socket,不支持cron job,不能创建子进程 • 限定时间内必须返回response • 应用必须是纯Python,不支持C的扩展
  6. 6. 存储−Datastore • 基于Google BigTable,分布式存储服务 • 面向对象,非 系型数据库,不支持ORM • 相同Model可以有不同的属性 • 支持查询,排序,事务 • 不支持join, sum, avg等,不支持存储过程 • 每次查询最多返回1000条记录 • 全文检索?
  7. 7. App Engine Service • Google帐号认证 • Gmail(发送email) • URL Fetch • Memcached • Image (PIL)
  8. 8. 价格(免费部分) Fixed Quota Per Day Usage Quotas 大约500万PV/月
  9. 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. 10. 申请Google App Engine • http://appengine.google.com/ • 通过Gmail帐号 • 通过短信认证 • 域名: http://yourapp.appspot.com • 可以通过Google Apps绑定自己的域名
  11. 11. 用途 • 学习Web 发 • 尝试各 idea, 少startup的前期投入成本 • 解决scalability问题 • App Gallery http://appgallery.appspot.com/
  12. 12. 未来计 • 对更多语言的支持 • 收费计 • 大数据量的上传和下载 • 离线处理 • 数据导入/导出
  13. 13. Django简介
  14. 14. Django简介 • 一个基于Python的full-stack Web框架 • ORM, URL mapping, admin interface, template, middleware, i18n, cache... • 很快很强大
  15. 15. 为什么用Django(而不是webapp) • Google App Engine Helper for Django • 功能更强大 • 可移植性
  16. 16. 项目示例−Blog系统 项目名称 − OnlyPython
  17. 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. 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. 19. app.yaml application:
onlypython version:
1 runtime:
python api_version:
1 handlers: ‐
url:
/static static_dir:
static ‐
url:
/.* 

script:
main.py
  20. 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. 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', 


)
  22. 22. TODO: 添加Blog
  23. 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()
  24. 24. forms.py from
google.appengine.ext.db
import
djangoforms
as
forms from
models
import
Post class
PostForm(forms.ModelForm): 



class
Meta: 







model
=
Post 







exclude
=
['author']
  25. 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. 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
%}
  27. 27. urls.py from
django.conf.urls.defaults
import
* urlpatterns
=
patterns('onlypy.blog.views', 



(r'^post/add/$',
'add_post'), )
  28. 28. Run • cd /yourpath/onlypython/ • python ./manage.py runserver 127.0.0.1:8000
  29. 29. http://localhost:8000/post/add/
  30. 30. TODO: 显示Blog列表
  31. 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. 32. index.yaml indexes: 



‐
kind:
Post 





properties: 





‐
name:
is_published 





‐
name:
create_time 







direction:
desc
  33. 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
%}
  34. 34. urls.py from
django.conf.urls.defaults
import
* urlpatterns
=
patterns('onlypy.blog.views', 



(r'^post/add/$',
'add_post'), 



(r'^$',
'list_post'), )
  35. 35. http://localhost:8000/
  36. 36. 项目信息 • 项目代码 http://code.google.com/p/onlypy/ • 项目演示 http://www.onlypython.com
  37. 37. Q&A

×