Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Gae Meets Django

3,703 views

Published on

  • 《 使用Django创建Google App Engine应用》
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

×