SlideShare a Scribd company logo
………
WECO Seminar Part II
How to build a personal portal on
Google App Engine with Django

                   Speaker : Jimmy Lu
                   Advisor : Hsing Mei

               Web Computing Laboratory
 Computer Science and Information Engineering Department
                Fu Jen Catholic University
Outline
• Design your personal portal
• Environment settings
       main.py
       settings.py
       app.yaml
• Implementation
• Demo
• Q&A
                      WECO Lab, CSIE dept., FJU
March 2, 2010                                     2
                        http://www.weco.net
Design your personal portal
• What elements should a personal portal
  have?
    Text: a simple blog
      - An editor
      - Posts archive
       Photos: upload and resize a profile picture
       Videos: fetch latest video you upload to your
          Youtube channel by Youtube API and embed
          it
       Widgets: embed Google Calendar and
                       WECO Lab, CSIE dept., FJU
March 2, 2010                                         3
          Google Map     http://www.weco.net
Environment settings                                     (1/5)



       main.py
      1. import os
      2. # point to seetings.py, then django knows how to configure the en
         vironment
      3. os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
      4.
      5. from google.appengine.ext.webapp.util import run_wsgi_app
      6. from google.appengine.dist import use_library
      7.
      8. # use_library('library_name', 'version'), impot django library
      9. use_library('django', '1.1')




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            4
                               http://www.weco.net
Environment settings                                       (2/5)


      10.
      11.   # django has implemented WSGI
      12.   import django.core.handlers.wsgi
      13.
      14.   def main():
      15.       # Create a Django application for WSGI.
      16.       application = django.core.handlers.wsgi.WSGIHandler()
      17.
      18.       # Run the WSGI CGI handler with that application.
      19.       run_wsgi_app(application)
      20.
      21.
      22.   if __name__ == '__main__':
      23.       main()



                               WECO Lab, CSIE dept., FJU
March 2, 2010                                                           5
                                 http://www.weco.net
Environment settings                                     (3/5)



       settings.py
      import os

      # Because the django database mapping is not work on Google App
         Engine, we need to leave the database settings empty.
      DATABASE_ENGINE = ''
      DATABASE_NAME = ''
      DATABASE_USER = ''
      DATABASE_PASSWORD = ''
      DATABASE_HOST = ''
      DATABASE_PORT = '‘

      # localization
      TIME_ZONE = 'Asia/Taipei’
      LANGUAGE_CODE = 'zh-TW '

                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                           6
                               http://www.weco.net
Environment settings                                     (4/5)


      # The path of the project root directory.
      ROOT_PATH = os.path.dirname(__file__)

      # Set the path where your templates locate.
      TEMPLATE_DIRS = (
          ROOT_PATH + '/templates',
      )

      INSTALLED_APPS = (
      #    'django.contrib.contenttypes',
      #    'django.contrib.sessions',
      )

      # Leave the others default.



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                    7
                               http://www.weco.net
Environment settings                                      (5/5)



• app.yaml
       Define the mapping of path to directory of
        static files(stylesheets, images, etc.) and the
        url.
         handlers:
         - url: /stylesheets
           static_dir: static/stylesheets

         - url: .*
           script: main.py



                              WECO Lab, CSIE dept., FJU
March 2, 2010                                                     8
                                http://www.weco.net
Implementation – models                                              (1/2)



• models.py
     We define three classes to store posts and
      pictures.
      1. class BlogPost(db.Model):
      2.      author = db.StringProperty()
      3.      title = db.StringProperty()
      4.      body = db.TextProperty()
      5.      # add the current time automatically.
      6.      timestamp = db.DateTimeProperty(auto_now_add = True)
      7.
      8. # a django form related to BlogPost.
      9. class BlogPostForm(djangoforms.ModelForm):
      10.     class Meta:
March 11.         model = BlogPost Lab, CSIE dept., FJU
                               WECO
      2, 2010                                                                9
                               http://www.weco.net
Implementation – models                                             (2/2)


      12.
      13.class Picture(db.Model):
      14.    # use BlobProperty to store a photo.
      15.    profilePicture = db.BlobProperty()
      16.    timestamp = db.DateTimeProperty(auto_now_add = True)




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                               10
                               http://www.weco.net
Implementation – views                                         (1/8)



• views.py
       Define a function to have an ability to edit a
        blog post and save it to the database.
      1. def edit(request):
      2.     # Use django form API, we can build a form object and display
          a form easily.
      3.     blogPostForm = BlogPostForm(data = request.POST or None)
      4.     t = loader.get_template("edit.html")
      5.     c = Context({ 'blogPostForm': blogPostForm })
      6.     blogPost = None
      7.     if blogPostForm.is_valid():



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            11
                               http://www.weco.net
Implementation – views                                           (2/8)


      8.           # Save the BlogPost object without save it to the databas
          e(commit = False).
      9.          blogPost = blogPostForm.save(commit = False)
      10.     if blogPost:
      11.         # Save it to the database.
      12.         blogPost.put()
      13.     if request.POST:
      14.         # Redirect to the main page.
      15.         return http.HttpResponseRedirect('/')
      16.
      17.     return HttpResponse(t.render(c))




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                             12
                               http://www.weco.net
Implementation – views                                           (3/8)



     Define a function to upload profile pictures.
      Notice that we use images API to resize the
      uploaded images.
      1. def upload(request):
      2.       if request.method == 'POST':
      3.           picture = Picture()
      4.           # Resize the picture by images API provided by Google App
            engine.
      5.           profile_picture = images.resize(request.FILES['img'].read
          (), 196, 196)
      6.           picture.profilePicture = db.Blob(profile_picture)
      7.           picture.put()
      8.           return http.HttpResponseRedirect('/')
      9.
                                WECO Lab, CSIE dept., FJU
March 10.
      2, 2010  return render_to_response('upload.html')                    13
                                http://www.weco.net
Implementation – views                                         (4/8)



       When a browser renders main.html, it will
        send request to the image source. By using
        url mapping, we map the url request to this
        function.
      1. def image(request):
      2.     # Get the picture by the key from database.
      3.     picture = Picture.get(request.GET['img_id'])
      4.     # Build your response
      5.     response = HttpResponse(picture.profilePicture)
      6.     # Set the content type to png because that's what the Google
         images api stores modified images as by default
      7.     response['Content-Type'] = 'image/png'
      8.
      9.     return response WECO Lab, CSIE dept., FJU
March 2, 2010                                                               14
                                http://www.weco.net
Implementation – views                                         (5/8)



       Use urlfetch API to fetch the response(XML
        format) from Youtube API and parse it to a
        DOM object. Then we can get the video id
        under “entry” elements.
      1. def video(request):
      2.     # From Youtube API document, you can get the url for getting
         your uploaded video.
      3.     url = "http://gdata.youtube.com/feeds/api/users/gn00023040/up
         loads"
      4.     # Fetch the result from url by urlfetch API provided by Googl
         e App engine.
      5.     result = urlfetch.fetch(url)
      6.     id = ''


                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            15
                               http://www.weco.net
Implementation – views                                          (6/8)


      7.      if result.status_code == 200:
      8.         # Parse the XML format by minidom which is a python build-
         in library.
      9.         xmldoc = minidom.parseString(result.content)
      10.         # An entry represents a video.
      11.         videos = xmldoc.getElementsByTagName('entry')
      12.         if videos:
      13.             # Get the first(latest) entry.
      14.             latest_video = videos[0]
      15.             id = latest_video.childNodes[0].childNodes[0].data[42:]

      16.
      17.       return id




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            16
                               http://www.weco.net
Implementation – views                                         (7/8)



• Send parameters to the templates to
  display post archive, profile picture, latest
  video and widgets.
      1. def main(request):
      2.     # Get all the posts chronologically.
      3.     posts = BlogPost.all().order('-timestamp')
      4.     # Store some parameters by Context dictionary.
      5.     c = Context()
      6.     c['posts'] = posts
      7.     c.push()
      8.     # Get the latest picture.
      9.     pictures = Picture.all().order('-timestamp').fetch(1)

                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                          17
                               http://www.weco.net
Implementation – views                                         (8/8)


      1.        if pictures:
      2.            picture = pictures[0]
      3.            c['image_key'] = picture.key()
      4.            c.push()
      5.        # Request to the video function.
      6.        video_id = video(request)
      7.        if video_id != '':
      8.            c['id'] = video_id
      9.            c.push()
      10.       # Load the template.
      11.       t = loader.get_template("main.html")
      12.
      13.    # Send the parameters to the template, then the template will
          process the result.
      14.    return HttpResponse(t.render(c))


                                WECO Lab, CSIE dept., FJU
March 2, 2010                                                           18
                                  http://www.weco.net
Implementation –
templates                  (1/6)

• edit.html
       {{blogPostForm}} display a form for editing a
        blog post.
      1. <form action="{%url views.edit%}" method="post">
      2.     <table>
      3.         <!-- Display the form by django's form API -->
      4.         {{blogPostForm}}
      5.         <tr>
      6.             <td><input type="submit" value="Post"></td>
      7.         </tr>
      8.     </table>
      9. </form>



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                      19
                               http://www.weco.net
Implementation –
templates                  (2/6)

• upload.html
       Make sure the enctype attribute should be
        multipart/from-data
      1. <!--
          Remember the enctype attribute of the form shold by multipart/fr
         om-data or request.FILES will receive nothing. -->
      2. <form action="{%url views.upload%}" method="post" enctype="multip
         art/form-data">
      3.     <input type="file" name="img" />
      4.     <input type="submit" value="Upload" />
      5. </form>



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            20
                               http://www.weco.net
Implementation –
templates                  (3/6)

• main.html
       Extend base.html and display post archive.
      1. {% extends "base.html" %}
      2. {% block content %}
      3.     <!-- Display all the posts iteratively -->
      4.     {% for post in posts %}
      5.         <h2>{{ post.title }}</h2>
      6.         <p>{{ post.timestamp|date:"l, F jS" }}</p>
      7.         <p>{{ post.body }}</p>
      8.     {% endfor %}
      9. {% endblock %}




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                 21
                               http://www.weco.net
Implementation –
templates                    (4/6)

• base.html
       Map the src=“image?img_id=…” to the image
        function and get the image id by
        request.GET[„image_id‟]
      1.   <h2>My Picture</h2>
      2.   <!-- If there is no profile picture, we will ask for one. -->
      3.   {% if image_key %}
      4.   <!--
            Django will map the url, 'image?img_id=...', to the image functi
           on and get the image_key by requets.GET -->
      5.   <img src="image?img_id={{ image_key }}"></img>
      6.   {% else %}
      7.   Click <a href="upload">here</a> to upload your profile picture!
      8.   {% endif %}
                               WECO Lab, CSIE dept., FJU
March 2, 2010                                                              22
                                 http://www.weco.net
Implementation –
templates                  (5/6)

       Embed your latest video by change the video
        id, {{id}}, to the embedded code provide by
        Youtube.
      1. <object width="425" height="344">
      2. <param name="movie" value="http://www.youtube.com/v/{{ id }}&hl=z
         h_TW&fs=1&"></param>
      3. <param name="allowFullScreen" value="true"></param>
      4. <param name="allowscriptaccess" value="always"></param>
      5. <embed src="http://www.youtube.com/v/{{ id }}&hl=zh_TW&fs=1&" typ
         e="application/x-shockwave-
         flash" allowscriptaccess="always" allowfullscreen="true" width="4
         25" height="344"></embed>
      6. </object>

                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            23
                               http://www.weco.net
Implementation –
templates                  (6/6)

       Where the result of main.html diplay.
      1. {% block content %}
      2. {% endblock %}


       We can also add some widgets here. Like
        Google Calendar or Google Map
      1. <h2>My Schedule</h2>
      2. <iframe src="http://www.google.com/calendar/embed?showTitle=0&sho
         wNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&mode=AGE
         NDA&height=400&wkst=1&bgcolor=%23453&src=weco.net_fm86efcblmn4qle
         bh9kometb6o%40group.calendar.google.com&color=%232952A3&ctz=Asia%
         2FTaipei" style=" border-
         width:0 " width="290" height="400" frameborder="0" scrolling="no"
         ></iframe>


                               WECO Lab, CSIE dept., FJU
March 2, 2010                                                            24
                                 http://www.weco.net
demo




                WECO Lab, CSIE dept., FJU
March 2, 2010                               25
                  http://www.weco.net
Q&A



Thanks for listening!

                WECO Lab, CSIE dept., FJU
March 2, 2010                               26
                  http://www.weco.net

More Related Content

PPTX
Hacking & cyber Security
PDF
Ethical Hacking and Cyber Security
PPTX
IT & telecommunication
PPTX
cyber security & hacking
PDF
History of Old School Hacking
PDF
Cyber Hacking & Security - IEEE - Univ of Houston 2015-04
PDF
Bootable Usb
PPT
WINDOW 7 INSTALL PROCESS
Hacking & cyber Security
Ethical Hacking and Cyber Security
IT & telecommunication
cyber security & hacking
History of Old School Hacking
Cyber Hacking & Security - IEEE - Univ of Houston 2015-04
Bootable Usb
WINDOW 7 INSTALL PROCESS

Viewers also liked (12)

PPTX
Cyber security and Hacking
PPT
Innovation at Microsoft
PDF
The Art of Cyber War: Cyber Security Strategies in a Rapidly Evolving Theatre
PPT
Learn More About Cyber Crime Investigation
PPTX
How to install Java and how to set the path
PPTX
WordPress Tutorial
PPTX
Cyber security 07
PPTX
PPTX
Cybercrime investigation
PPT
cyber terrorism
PPT
Beginners PHP Tutorial
PPT
Area-51
Cyber security and Hacking
Innovation at Microsoft
The Art of Cyber War: Cyber Security Strategies in a Rapidly Evolving Theatre
Learn More About Cyber Crime Investigation
How to install Java and how to set the path
WordPress Tutorial
Cyber security 07
Cybercrime investigation
cyber terrorism
Beginners PHP Tutorial
Area-51
Ad

Similar to How To Build A Personal Portal On Google App Engine With Django (20)

PDF
Django at Scale
PDF
Gae Meets Django
PDF
Google app-engine-with-python
PDF
Google App Engine in 40 minutes (the absolute essentials)
PDF
OSCON Google App Engine Codelab - July 2010
PPTX
Googleappengineintro 110410190620-phpapp01
KEY
國民雲端架構 Django + GAE
PDF
GDG Addis - An Introduction to Django and App Engine
PDF
Introduction to App Engine Development
PDF
Building Pluggable Web Applications using Django
PDF
a hands on guide to django
KEY
Jumpstart Django
PDF
App Engine
PPTX
PDF
Web Development with Python and Django
PDF
Django for mobile applications
PDF
Introduction to Django
PDF
Django Overview
PDF
App Engine On Air: Munich
PPTX
Django Architecture Introduction
Django at Scale
Gae Meets Django
Google app-engine-with-python
Google App Engine in 40 minutes (the absolute essentials)
OSCON Google App Engine Codelab - July 2010
Googleappengineintro 110410190620-phpapp01
國民雲端架構 Django + GAE
GDG Addis - An Introduction to Django and App Engine
Introduction to App Engine Development
Building Pluggable Web Applications using Django
a hands on guide to django
Jumpstart Django
App Engine
Web Development with Python and Django
Django for mobile applications
Introduction to Django
Django Overview
App Engine On Air: Munich
Django Architecture Introduction
Ad

More from Jimmy Lu (20)

PPTX
All the troubles you get into when setting up a production ready Kubernetes c...
PPTX
A Million ways of Deploying a Kubernetes Cluster
PPTX
Renaissance of JUnit - Introduction to JUnit 5
PPTX
Event sourcing with reactor and spring statemachine
PPTX
Bootify your spring application
PPTX
A Prototype of Brain Network Simulator for Spatiotemporal Dynamics of Alzheim...
PPTX
The Model of Spatiotemporal Dynamics of Alzheimer’s Disease
PPTX
The Models of Alzheimer's Disease Part II
PPTX
The Models of Alzheimer's Disease Part I
PPTX
The Models of Alzheimer's Disease Part III
PPTX
On the Development of a Brain Simulator
PPTX
Design the Brain Simulator
PPTX
Research Proposal and Milestone
PPTX
Reward
PPTX
On the Development of a Brain Simulator
PPTX
Mining the Parkinson's Telemonitoring Data Set
PPTX
Brian Simulator (a draft)
PPTX
Exploring Complex Networks
PPTX
Brain Network - Thalamocortical Motif
PPTX
Brain Networks
All the troubles you get into when setting up a production ready Kubernetes c...
A Million ways of Deploying a Kubernetes Cluster
Renaissance of JUnit - Introduction to JUnit 5
Event sourcing with reactor and spring statemachine
Bootify your spring application
A Prototype of Brain Network Simulator for Spatiotemporal Dynamics of Alzheim...
The Model of Spatiotemporal Dynamics of Alzheimer’s Disease
The Models of Alzheimer's Disease Part II
The Models of Alzheimer's Disease Part I
The Models of Alzheimer's Disease Part III
On the Development of a Brain Simulator
Design the Brain Simulator
Research Proposal and Milestone
Reward
On the Development of a Brain Simulator
Mining the Parkinson's Telemonitoring Data Set
Brian Simulator (a draft)
Exploring Complex Networks
Brain Network - Thalamocortical Motif
Brain Networks

Recently uploaded (20)

PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
MYSQL Presentation for SQL database connectivity
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Machine Learning_overview_presentation.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPT
Teaching material agriculture food technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
cuic standard and advanced reporting.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Electronic commerce courselecture one. Pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Digital-Transformation-Roadmap-for-Companies.pptx
MYSQL Presentation for SQL database connectivity
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Diabetes mellitus diagnosis method based random forest with bat algorithm
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Machine Learning_overview_presentation.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Encapsulation_ Review paper, used for researhc scholars
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
A comparative analysis of optical character recognition models for extracting...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Teaching material agriculture food technology
Reach Out and Touch Someone: Haptics and Empathic Computing
cuic standard and advanced reporting.pdf
Programs and apps: productivity, graphics, security and other tools
Electronic commerce courselecture one. Pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11

How To Build A Personal Portal On Google App Engine With Django

  • 1. ……… WECO Seminar Part II How to build a personal portal on Google App Engine with Django Speaker : Jimmy Lu Advisor : Hsing Mei Web Computing Laboratory Computer Science and Information Engineering Department Fu Jen Catholic University
  • 2. Outline • Design your personal portal • Environment settings  main.py  settings.py  app.yaml • Implementation • Demo • Q&A WECO Lab, CSIE dept., FJU March 2, 2010 2 http://www.weco.net
  • 3. Design your personal portal • What elements should a personal portal have?  Text: a simple blog - An editor - Posts archive  Photos: upload and resize a profile picture  Videos: fetch latest video you upload to your Youtube channel by Youtube API and embed it  Widgets: embed Google Calendar and WECO Lab, CSIE dept., FJU March 2, 2010 3 Google Map http://www.weco.net
  • 4. Environment settings (1/5)  main.py 1. import os 2. # point to seetings.py, then django knows how to configure the en vironment 3. os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' 4. 5. from google.appengine.ext.webapp.util import run_wsgi_app 6. from google.appengine.dist import use_library 7. 8. # use_library('library_name', 'version'), impot django library 9. use_library('django', '1.1') WECO Lab, CSIE dept., FJU March 2, 2010 4 http://www.weco.net
  • 5. Environment settings (2/5) 10. 11. # django has implemented WSGI 12. import django.core.handlers.wsgi 13. 14. def main(): 15. # Create a Django application for WSGI. 16. application = django.core.handlers.wsgi.WSGIHandler() 17. 18. # Run the WSGI CGI handler with that application. 19. run_wsgi_app(application) 20. 21. 22. if __name__ == '__main__': 23. main() WECO Lab, CSIE dept., FJU March 2, 2010 5 http://www.weco.net
  • 6. Environment settings (3/5)  settings.py import os # Because the django database mapping is not work on Google App Engine, we need to leave the database settings empty. DATABASE_ENGINE = '' DATABASE_NAME = '' DATABASE_USER = '' DATABASE_PASSWORD = '' DATABASE_HOST = '' DATABASE_PORT = '‘ # localization TIME_ZONE = 'Asia/Taipei’ LANGUAGE_CODE = 'zh-TW ' WECO Lab, CSIE dept., FJU March 2, 2010 6 http://www.weco.net
  • 7. Environment settings (4/5) # The path of the project root directory. ROOT_PATH = os.path.dirname(__file__) # Set the path where your templates locate. TEMPLATE_DIRS = ( ROOT_PATH + '/templates', ) INSTALLED_APPS = ( # 'django.contrib.contenttypes', # 'django.contrib.sessions', ) # Leave the others default. WECO Lab, CSIE dept., FJU March 2, 2010 7 http://www.weco.net
  • 8. Environment settings (5/5) • app.yaml  Define the mapping of path to directory of static files(stylesheets, images, etc.) and the url.  handlers:  - url: /stylesheets  static_dir: static/stylesheets  - url: .*  script: main.py WECO Lab, CSIE dept., FJU March 2, 2010 8 http://www.weco.net
  • 9. Implementation – models (1/2) • models.py  We define three classes to store posts and pictures. 1. class BlogPost(db.Model): 2. author = db.StringProperty() 3. title = db.StringProperty() 4. body = db.TextProperty() 5. # add the current time automatically. 6. timestamp = db.DateTimeProperty(auto_now_add = True) 7. 8. # a django form related to BlogPost. 9. class BlogPostForm(djangoforms.ModelForm): 10. class Meta: March 11. model = BlogPost Lab, CSIE dept., FJU WECO 2, 2010 9 http://www.weco.net
  • 10. Implementation – models (2/2) 12. 13.class Picture(db.Model): 14. # use BlobProperty to store a photo. 15. profilePicture = db.BlobProperty() 16. timestamp = db.DateTimeProperty(auto_now_add = True) WECO Lab, CSIE dept., FJU March 2, 2010 10 http://www.weco.net
  • 11. Implementation – views (1/8) • views.py  Define a function to have an ability to edit a blog post and save it to the database. 1. def edit(request): 2. # Use django form API, we can build a form object and display a form easily. 3. blogPostForm = BlogPostForm(data = request.POST or None) 4. t = loader.get_template("edit.html") 5. c = Context({ 'blogPostForm': blogPostForm }) 6. blogPost = None 7. if blogPostForm.is_valid(): WECO Lab, CSIE dept., FJU March 2, 2010 11 http://www.weco.net
  • 12. Implementation – views (2/8) 8. # Save the BlogPost object without save it to the databas e(commit = False). 9. blogPost = blogPostForm.save(commit = False) 10. if blogPost: 11. # Save it to the database. 12. blogPost.put() 13. if request.POST: 14. # Redirect to the main page. 15. return http.HttpResponseRedirect('/') 16. 17. return HttpResponse(t.render(c)) WECO Lab, CSIE dept., FJU March 2, 2010 12 http://www.weco.net
  • 13. Implementation – views (3/8)  Define a function to upload profile pictures. Notice that we use images API to resize the uploaded images. 1. def upload(request): 2. if request.method == 'POST': 3. picture = Picture() 4. # Resize the picture by images API provided by Google App engine. 5. profile_picture = images.resize(request.FILES['img'].read (), 196, 196) 6. picture.profilePicture = db.Blob(profile_picture) 7. picture.put() 8. return http.HttpResponseRedirect('/') 9. WECO Lab, CSIE dept., FJU March 10. 2, 2010 return render_to_response('upload.html') 13 http://www.weco.net
  • 14. Implementation – views (4/8)  When a browser renders main.html, it will send request to the image source. By using url mapping, we map the url request to this function. 1. def image(request): 2. # Get the picture by the key from database. 3. picture = Picture.get(request.GET['img_id']) 4. # Build your response 5. response = HttpResponse(picture.profilePicture) 6. # Set the content type to png because that's what the Google images api stores modified images as by default 7. response['Content-Type'] = 'image/png' 8. 9. return response WECO Lab, CSIE dept., FJU March 2, 2010 14 http://www.weco.net
  • 15. Implementation – views (5/8)  Use urlfetch API to fetch the response(XML format) from Youtube API and parse it to a DOM object. Then we can get the video id under “entry” elements. 1. def video(request): 2. # From Youtube API document, you can get the url for getting your uploaded video. 3. url = "http://gdata.youtube.com/feeds/api/users/gn00023040/up loads" 4. # Fetch the result from url by urlfetch API provided by Googl e App engine. 5. result = urlfetch.fetch(url) 6. id = '' WECO Lab, CSIE dept., FJU March 2, 2010 15 http://www.weco.net
  • 16. Implementation – views (6/8) 7. if result.status_code == 200: 8. # Parse the XML format by minidom which is a python build- in library. 9. xmldoc = minidom.parseString(result.content) 10. # An entry represents a video. 11. videos = xmldoc.getElementsByTagName('entry') 12. if videos: 13. # Get the first(latest) entry. 14. latest_video = videos[0] 15. id = latest_video.childNodes[0].childNodes[0].data[42:] 16. 17. return id WECO Lab, CSIE dept., FJU March 2, 2010 16 http://www.weco.net
  • 17. Implementation – views (7/8) • Send parameters to the templates to display post archive, profile picture, latest video and widgets. 1. def main(request): 2. # Get all the posts chronologically. 3. posts = BlogPost.all().order('-timestamp') 4. # Store some parameters by Context dictionary. 5. c = Context() 6. c['posts'] = posts 7. c.push() 8. # Get the latest picture. 9. pictures = Picture.all().order('-timestamp').fetch(1) WECO Lab, CSIE dept., FJU March 2, 2010 17 http://www.weco.net
  • 18. Implementation – views (8/8) 1. if pictures: 2. picture = pictures[0] 3. c['image_key'] = picture.key() 4. c.push() 5. # Request to the video function. 6. video_id = video(request) 7. if video_id != '': 8. c['id'] = video_id 9. c.push() 10. # Load the template. 11. t = loader.get_template("main.html") 12. 13. # Send the parameters to the template, then the template will process the result. 14. return HttpResponse(t.render(c)) WECO Lab, CSIE dept., FJU March 2, 2010 18 http://www.weco.net
  • 19. Implementation – templates (1/6) • edit.html  {{blogPostForm}} display a form for editing a blog post. 1. <form action="{%url views.edit%}" method="post"> 2. <table> 3. <!-- Display the form by django's form API --> 4. {{blogPostForm}} 5. <tr> 6. <td><input type="submit" value="Post"></td> 7. </tr> 8. </table> 9. </form> WECO Lab, CSIE dept., FJU March 2, 2010 19 http://www.weco.net
  • 20. Implementation – templates (2/6) • upload.html  Make sure the enctype attribute should be multipart/from-data 1. <!-- Remember the enctype attribute of the form shold by multipart/fr om-data or request.FILES will receive nothing. --> 2. <form action="{%url views.upload%}" method="post" enctype="multip art/form-data"> 3. <input type="file" name="img" /> 4. <input type="submit" value="Upload" /> 5. </form> WECO Lab, CSIE dept., FJU March 2, 2010 20 http://www.weco.net
  • 21. Implementation – templates (3/6) • main.html  Extend base.html and display post archive. 1. {% extends "base.html" %} 2. {% block content %} 3. <!-- Display all the posts iteratively --> 4. {% for post in posts %} 5. <h2>{{ post.title }}</h2> 6. <p>{{ post.timestamp|date:"l, F jS" }}</p> 7. <p>{{ post.body }}</p> 8. {% endfor %} 9. {% endblock %} WECO Lab, CSIE dept., FJU March 2, 2010 21 http://www.weco.net
  • 22. Implementation – templates (4/6) • base.html  Map the src=“image?img_id=…” to the image function and get the image id by request.GET[„image_id‟] 1. <h2>My Picture</h2> 2. <!-- If there is no profile picture, we will ask for one. --> 3. {% if image_key %} 4. <!-- Django will map the url, 'image?img_id=...', to the image functi on and get the image_key by requets.GET --> 5. <img src="image?img_id={{ image_key }}"></img> 6. {% else %} 7. Click <a href="upload">here</a> to upload your profile picture! 8. {% endif %} WECO Lab, CSIE dept., FJU March 2, 2010 22 http://www.weco.net
  • 23. Implementation – templates (5/6)  Embed your latest video by change the video id, {{id}}, to the embedded code provide by Youtube. 1. <object width="425" height="344"> 2. <param name="movie" value="http://www.youtube.com/v/{{ id }}&hl=z h_TW&fs=1&"></param> 3. <param name="allowFullScreen" value="true"></param> 4. <param name="allowscriptaccess" value="always"></param> 5. <embed src="http://www.youtube.com/v/{{ id }}&hl=zh_TW&fs=1&" typ e="application/x-shockwave- flash" allowscriptaccess="always" allowfullscreen="true" width="4 25" height="344"></embed> 6. </object> WECO Lab, CSIE dept., FJU March 2, 2010 23 http://www.weco.net
  • 24. Implementation – templates (6/6)  Where the result of main.html diplay. 1. {% block content %} 2. {% endblock %}  We can also add some widgets here. Like Google Calendar or Google Map 1. <h2>My Schedule</h2> 2. <iframe src="http://www.google.com/calendar/embed?showTitle=0&sho wNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&mode=AGE NDA&height=400&wkst=1&bgcolor=%23453&src=weco.net_fm86efcblmn4qle bh9kometb6o%40group.calendar.google.com&color=%232952A3&ctz=Asia% 2FTaipei" style=" border- width:0 " width="290" height="400" frameborder="0" scrolling="no" ></iframe> WECO Lab, CSIE dept., FJU March 2, 2010 24 http://www.weco.net
  • 25. demo WECO Lab, CSIE dept., FJU March 2, 2010 25 http://www.weco.net
  • 26. Q&A Thanks for listening! WECO Lab, CSIE dept., FJU March 2, 2010 26 http://www.weco.net