gae meets django

37
使用DjangoGoogle App Engine[email protected]

Upload: guest96a888

Post on 02-Jul-2015

1.586 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: GAE Meets Django

使用Django创建Google App Engine应用

林胜[email protected]

Page 2: GAE Meets Django

• Google App Engine介绍

• Django介绍

• 代码示例

Page 3: GAE Meets Django

Google App Engine介绍

Page 4: GAE Meets Django

什么是Google App Engine• Google的Web Hosting服务

•将你的Web应用部署到Google的基础设施之上

•使你的应用能够自动Scaling和load balancing

•提供数据存储服务

•集成了Google User认证和Gmail等服务

Page 5: GAE Meets Django

运行环境和限制• Python 2.5.2

•内置Django 0.96.1,并支持所有支持CGI的框架(以及任何使用CGI适配器的WSGI框架)

•运行在Sandbox中,不能访问文件系统,不能建立socket,不支持cron job,不能创建子进程

•限定时间内必须返回response

•应用必须是纯Python,不支持C的扩展

Page 6: GAE Meets Django

存储-Datastore•基于Google BigTable,分布式存储服务

•面向对象,非关系型数据库,不支持ORM

•相同Model可以有不同的属性

•支持查询,排序,事务

•不支持join, sum, avg等,不支持存储过程

•每次查询最多返回1000条记录

•全文检索?

Page 7: GAE Meets Django

App Engine Service

• Google帐号认证

• Gmail(发送email)

• URL Fetch

• Memcached

• Image (PIL)

Page 8: GAE Meets Django

价格(免费部分)Fixed Quota Per Day Usage Quotas

大约500万PV/月

Page 9: GAE Meets Django

价格(收费部分)

• $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

Page 10: GAE Meets Django

申请Google App Engine• http://appengine.google.com/

•通过Gmail帐号

•通过短信认证

•域名: http://yourapp.appspot.com

•可以通过Google Apps绑定自己的域名

Page 11: GAE Meets Django

用途

•学习Web开发

•尝试各种idea, 减少startup的前期投入成本

•解决scalability问题

• App Gallery http://appgallery.appspot.com/

Page 12: GAE Meets Django

未来计划•对更多语言的支持

•收费计划

•大数据量的上传和下载

•离线处理

•数据导入/导出

Page 13: GAE Meets Django

Django简介

Page 14: GAE Meets Django

Django简介

•一个基于Python的full-stack Web框架

• ORM, URL mapping, admin interface, template, middleware, i18n, cache...

•很快很强大

Page 15: GAE Meets Django

为什么用Django(而不是webapp)

• Google App Engine Helper for Django

•功能更强大

•可移植性

Page 16: GAE Meets Django

项目示例-Blog系统

项目名称 - OnlyPython

Page 17: GAE Meets Django

创建开发环境

• 下载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/

Page 18: GAE Meets Django

项目目录结构--- 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)

Page 19: GAE Meets Django

app.yamlapplication:onlypython

version:1

runtime:python

api_version:1

handlers:

‐url:/static

static_dir:static

‐url:/.*

script:main.py

Page 20: GAE Meets Django

main.pyimportosimportsysimportlogging

fromappengine_djangoimportInstallAppengineHelperForDjangoInstallAppengineHelperForDjango()

#GoogleAppEngineimports.fromgoogle.appengine.ext.webappimportutil

#ImportthepartofDjangothatweusehere.importdjango.core.handlers.wsgi

defmain():#CreateaDjangoapplicationforWSGI.application=django.core.handlers.wsgi.WSGIHandler()

#RuntheWSGICGIhandlerwiththatapplication.util.run_wsgi_app(application)

if__name__=='__main__':main()

Page 21: GAE Meets Django

settings.pyTIME_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',

)

Page 22: GAE Meets Django

TODO: 添加Blog

Page 23: GAE Meets Django

models.pyfromgoogle.appengine.extimportdb

classCategory(db.Model):name=db.StringProperty()def__str__(self):returnself.name

classPost(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'已发布')

defget_absolute_url(self):return'/post/%s/'%self.key().id()

Page 24: GAE Meets Django

forms.pyfromgoogle.appengine.ext.dbimportdjangoformsasformsfrommodelsimportPost

classPostForm(forms.ModelForm):classMeta:model=Postexclude=['author']

Page 25: GAE Meets Django

views.pydefadd_post(request):

ifrequest.method=='GET':form=PostForm()ifrequest.method=='POST':form=PostForm(request.POST)ifform.is_valid():post=form.save()post.author=users.get_current_user()post.put()returnHttpResponseRedirect('/post/add/')

returnrender_to_response('blog/add_post.html',{'form':form},context_instance=RequestContext(request))

Page 26: GAE Meets Django

add_post.html{%extends"base.html"%}

{%blockcontent%}<h1>添加新文章</h1>

<formname="mainForm"method="post"action="">{{form.as_p}}<inputtype="submit"value="保存"/>

</form>{%endblock%}

Page 27: GAE Meets Django

urls.pyfromdjango.conf.urls.defaultsimport*

urlpatterns=patterns('onlypy.blog.views',(r'^post/add/$','add_post'),)

Page 28: GAE Meets Django

Run• cd /yourpath/onlypython/

• python ./manage.py runserver 127.0.0.1:8000

Page 30: GAE Meets Django

TODO: 显示Blog列表

Page 31: GAE Meets Django

views.pydeflist_post(request):

posts=Post.all().order('‐create_time')if(notis_admin()):posts=posts.filter("is_published",True)returnobject_list(request,queryset=posts,allow_empty=True,template_name='blog/list_post.html',extra_context={'is_admin':is_admin()},paginate_by=20)

Page 32: GAE Meets Django

index.yamlindexes:

‐kind:Postproperties:‐name:is_published‐name:create_timedirection:desc

Page 33: GAE Meets Django

list_post.html{%extends"base.html"%}{%loadmarkup%}{%loadpaginator%}

{%blockcontent%}{%forpostinobject_list%}<tableborder="0"cellspacing="0"cellpadding="0"width="100%"><tr><tdvalign="top"><h1style="margin‐bottom:2px;"><ahref="/post/{{post.key.id}}">[{{post.category.name}}]{{post.title}}{%ifpost.is_published%}{%else%}(未发布){%endif%}

</a></h1><pstyle="padding:0px;margin:0px;"class="small_font">类别:<ahref="/category/

{{post.category.key.id}}/">{{post.category.name}}</a><spanstyle="padding‐left:10px;">{{post.author.nickname}}写于{{post.create_time|date:"Y‐M‐dH:i"}}</span>

</p></td></tr></table><divstyle="padding‐left:30px;">{{post.content|markdown}}</div>{%endfor%}{%paginator%}{%endblock%}

Page 34: GAE Meets Django

urls.pyfromdjango.conf.urls.defaultsimport*

urlpatterns=patterns('onlypy.blog.views',(r'^post/add/$','add_post'),(r'^$','list_post'),)

Page 36: GAE Meets Django

项目信息• 项目代码 http://code.google.com/p/onlypy/

• 项目演示 http://www.onlypython.com

Page 37: GAE Meets Django

Q&A