accelerating information technology innovationgsl-archive.mit.edu/.../materials/l3.pdf · 2014. 1....

Post on 07-Nov-2020

4 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Accelerating Information Technology

Innovation

http://aiti.mit.edu/program/philippines-summer-2012/

Philippines Summer 2012 Lecture 3 – Rapid Application Development with Python

June 26, 2012

Agenda

•  Introduction to MVC and Django •  Django Models •  Django Views •  Django Templates

2

Google App Engine / Heroku / Your own Webserver

Your Django app

Mobile Web Browser/ Mobile Web App/ Desktop Browser

The Big Picture

What is a Web Application Framework?

•  A framework (a.k.a. code libraries) that provides functionality for common components in a website, web app, or web service.

•  Eases coding for –  Working with forms –  Handling HTTP requests –  Templates for common HTML layouts –  URL mapping –  Database communication –  Session management –  Site security

•  Allows you to focus on design and functionality rather than small details.

Mini Quiz

5

• How does a web server work?

• What is the most popular web server?

• What is the most popular mobile web browser?

• What is the W3C? What do they do?

• What is the IETF? What do they do?

Mini Quiz Answers

6

• Via HTTP protocol

• Apache

• Android Robot

• World Wide Web Consortium: They develop standards for the web

• Internet Engineering Task Force: They develop standards for the Internet

Web Application Frameworks

7

Python Web Application Frameworks for Backend

Model-View-Controller (MVC) •  A paradigm for organizing code often seen in

web app frameworks •  Main idea is:

– Separate the storage and manipulation of data (the model) and the presentation of data (view)

– Use the Controller to communicate between the model and view

•  Advantages – Easier to develop and test model and view

independently – Easier for others to understand

Model-View-Controller (MVC) (news site example)

Controller

View Model

•  News stories and images in a database

•  User comments

•  Layout of stories on mobile phone or desktop browser

Send request for a story

Asks the model for the story and

its user comments

Serves requested story

Django

•  Web application framework, written in Python •  Released 2005 •  Began with World Online, that needed to

rapidly develop applications for news sites. •  Named after gypsy jazz guitarist Django

Reinhardt (1910-53)

•  Follows the Model-View-Controller paradigm

Model-View-Controller (MVC) (news site example with Django)

Controller

View Model

•  News stories and images in a database

•  User comments

•  Layout of stories on mobile phone or desktop browser

Send request for a story

Asks the model for the story and

its user comments

Serves requested story

Model

View

Template

Django Models

13

What is a model?  A class describing data in your application with attributes for each data field that you care about

 The schema for your data

14

Why use Django models?  Avoid direct work with the database

 No need to handle database connections, timeouts, etc. Let Django do it for you.

15

Django Fields All you do is define a field type

Ex: active = models.BooleanField() ‏

Django handles the rest: • Bit value in sql database

• Represented as a checkbox on a webpage

• Validation of values

16

Before Models: from django.shortcuts import render_to_response import MySQLdb

def book_list(request): db = MySQLdb.connect(user='me', db='mydb',

passwd='secret', host='localhost') ‏ cursor = db.cursor() ‏ cursor.execute('SELECT name FROM books ORDER BY name')‏ names = [row[0] for row in cursor.fetchall()]

db.close() ‏

return render_to_response('book_list.html', {'names': names})‏

After Models:

from django.shortcuts import render_to_response from mysite.books.models import Book

def book_list(request):

books = Book.objects.order_by('name') ‏

return render_to_response('book_list.html', {'books': books})‏

Django Model Syntax class Musician(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) instrument = models.CharField(max_length=100) ‏ def __unicode__(): return last_name+”, “+first_name

class Album(models.Model): name = models.CharField(max_length=100) release_date = models.DateField() num_stars = models.IntegerField() ‏ artist = models.ForeignKey(Musician) def __unicode__(): return name

19

Field Options blank: if True, field is allowed to be blank. default is False.

null: if True, empty fields will be stored as NULL in database.

choices: list of 2-tuples, will create a select box instead of CharField

class Foo(models.Model): GENDER_CHOICES = ( ('M', 'Male'), ('F', 'Female'), (‘NS’, ‘Not specified’) ) gender = models.CharField(max_length=2, choices=GENDER_CHOICES)

20

Field Options

default: default value for a field

primary_key: if True, this field is the primary key for the model

unique: if True, this will have to be unique throughout the table

verbose_field_name: provides a human readable file name

21

Django Relationship Fields ForeignKey ( foreign class ) Many-to-one

ManyToManyField (foreign class) Uses a temporary table to join tables together

OneToOneField ( foreign class ) Enforces uniqueness, i.e. foreign key with unique=True

22

Django Model Syntax class Musician(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) instrument = models.CharField(max_length=100) ‏ def __unicode__(): return last_name+”, “+first_name

class Album(models.Model): artist = models.ForeignKey(Musician) name = models.CharField(max_length=100) release_date = models.DateField() num_stars = models.IntegerField() ‏ def __unicode__(): return name

23

Creating Models Manually

24

>>> from music.models import Musician

>>> m1 = Musician(first_name='Jimi', last_name='Hendrix', instrument='guitar')‏

>>> m1.save()‏

>>> m2 = Musician(first_name="Eric", last_name=”Clapton”, instrument='guitar')‏

>>> m2.save()‏

>>> Musician_list = Musician.objects.all() ‏

>>> Musician_list [<Musician: Hendrix, Jimi>, <Musician: Clapton, Eric>]

#remember the unicode!!

Filtering

25

>>>Musician.objects.filter(first_name=”Jimi”) ‏[<Musician: Hendrix, Jimi>]

>>>Musician.objects.filter(instrument=”guitar”)‏ [<Musician: Hendrix, Jimi>, <Musician: Clapton, Eric>]

#returns a QuerySet, not an individual Model Object

>>>Musician.objects.filter(last_name__contains=”Clap”)‏ [<Musician: Clapton, Eric>]

#double underscore!!

Getting

26

>>>Musician.objects.get(first_name=”Jimi”) ‏<Musician: Hendrix, Jimi>

#returns single object

>>>Musician.objects.get(instrument=”violin”)‏ Error! DoesNotExist

>>>Musician.objects.get(instrument=”guitar”)‏ Error! MultipleObjectsReturned

#use try/except when using “get”.

Ordering

27

>>>Musician.objects.order_by(-last_name) ‏[<Musician: Hendrix, Jimi>, <Musician: Clapton, Eric>]

Easier way: add class Meta to Model class

class Musician(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) instrument = models.CharField(max_length=100)

def __unicode__(): return last_name+”, “+first_name

class Meta: ordering = [-last_name]

More Functionality

28

>>>m1.instrument=”drums” >>>m1.save() #updates ALL rows, could lead to “race” condition

>>>Musicians.objects.filter(id=12).update(instrument=”bass”)‏ #updates only “instrument” row

Chaining

>>>Musicians.objects.filter(instrument="guitar").order_by("-last_name")‏ [<Musician: Hendrix, Jimi>, <Musician: Clapton, Eric>]

Rules of Django Models 1. When you update a model, ALWAYS RUN python manage.py syncdb

2. All classes extend models.Model

3. Models only live in Apps

4. Django doesn't save objects until you call save() method

>>>a1 = Album(...)‏ # a1 is not saved to the database yet! >>>a1.save()‏ # Now it is.

29

Tips for Django Models 1. Keep code clean

2. Always create a __unicode__() method

3. Name your variables well

4. Don’t think too much about the database

30

Django Views

31

Views

•  What are they (who did the reading??)

•  Views are the logical interface between data (Models) and presentation (Templates)

Hello World

#inside views.py (create it)

from django.http import HttpResponse def hello(request):

return HttpResponse("Hello world“)

# EVERY view takes a request object as first parameter

# EVERY view returns an HttpResponse object

How to hook it up?

#use urls.py

from django.conf.urls.defaults import * from mysite.views import hello urlpatterns = patterns('',

('^hello/$', hello), )

Request Life Cycle 1.  A request comes in to /hello/. 2.  Django determines the root URLconf by looking at the

ROOT_URLCONF setting. 3.  Django looks at all of the URLpatterns in the URLconf

for the first one that matches /hello/. 4.  If it finds a match, it calls the associated view function. 5.  The view function returns an HttpResponse. 6.  Django converts the HttpResponse to the proper HTTP

response, which results in a Web page.

Dynamic Content

from django.conf.urls.defaults import * from mysite.views import hello, current_datetime,

hours_ahead

urlpatterns = patterns('', (r'^hello/$', hello), (r'^time/$', current_datetime),

)

Dynamic Content from django.http import HttpResponse import datetime

def hello(request): return HttpResponse("Hello world")

def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)

Dynamic URLs from django.conf.urls.defaults import * from mysite.views import hello, current_datetime,

hours_ahead

urlpatterns = patterns('', (r'^hello/$', hello), (r'^time/$', current_datetime), (r'^time/plus/(\d{1,2})/$', hours_ahead),

)

Dynamic URLs from django.http import Http404, HttpResponse import datetime def hours_ahead(request, offset):

try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "<html><body>In %s hour(s), it will be %s.</ body></html>" % (offset, dt)

return HttpResponse(html)

A Note about Development

Where to start, views or URLconfs? •  Big Picture: Start with URLconfs

–  get an idea of what kind of content you need to deliver –  to-do list

•  Bottom Up: Start with Views –  first make the pieces, then put the puzzle together

Tricks with URLconfs

Factor out common prefixes Before:

urlpatterns = patterns('', (r'^one/$', myapp.views.someView), (r'^two/$', myapp.views.someOtherView), (r'^three/$', myapp.views.evenOtherView),

)

Tricks with URLconfs

Factor out common prefixes After:

urlpatterns = patterns(‘myapp.views', (r'^one/$', someView), (r'^two/$', someOtherView), (r'^three/$', evenOtherView),

) urlpatterns+= patterns(‘myotherapp.views’, ….

Extra Parameters to Views # urls.py from django.conf.urls.defaults import * from mysite import views

urlpatterns = patterns('', (r'^listStyle1/$', views.list_view, {'template_name':'template1.html'}),

(r'^listStyle2/$', views.list_view, {'template_name': 'template2.html'}), )

Extra Parameters to Views # views.py from django.shortcuts import render_to_response from mysite.models import MyModel

def list_view(request, template_name): m_list = MyModel.objects.filter(is_new=True) return render_to_response(template_name, {'m_list': m_list})

Extra Parameters to Views # views.py from django.shortcuts import render_to_response from mysite.models import MyModel

def list_view(request, template_name): m_list = MyModel.objects.filter(is_new=True) return render_to_response(template_name, {'m_list': m_list}) ^^ ̂ #this is called TEMPLATE CONTEXT

Generic Views

•  Django comes with some commonly used views –  redirect a user to another page –  render a specific template – display list and detail view of objects – display date-based objects in archive pages

Generic Views #Example: direct_to_template

from django.conf.urls.defaults import * from django.views.generic.simple import direct_to_template

urlpatterns = patterns('', (r'^about/$', direct_to_template, { 'template': 'about.html' })

)

#Magic!!

Loose Coupling

•  Changes made to one piece of code should have little or no effect on other pieces of code –  to change URL from “/hours_ahead” to “/

plus_hours”, need to change only URLconf –  to change View from calculating “hours

ahead” to “hours ago”, need to change only view

– Allows linking multiple URLs to the same view

Loose Coupling def hours_ahead(request, offset):

try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset)

html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt) return HttpResponse(html)

#HTML should be in a Template!!

Django Templates

50

weather.html <html>

<head> <title> Weather </title> </head>

<body> <p>Today’s weather in {{ city }} is {{ description }}.</p> <div id=“temperature”> {% for day in thisWeek %} <li> On {{ day.date }}, the temperature will be {{ day.temperature }}. </li> {% endfor %}

</div> <div id="ads"> {% block ads %} Click on these ads! {% endblock %} </div> </body> </html>

Today’s weather in Manila is sunny.

•  On Thursday, the temperature will be 20.

•  On Friday, the temperature will be 25. •  On Saturday, the temperature will be

22.

Click on these ads!

city  =  ‘Manila‘  descrip1on  =  'sunny‘  thisWeek  =  [dict(date='Thursday',  temperature=20),                                              dict(date='Friday',  temperature=25),                                              dict(date='Saturday',  temperature=22)]  

Context  

Displayed  by  browser  

Syntax template.render(context)

week = [dict(date='Thursday', temperature=20), dict(date='Friday', temperature=25), dict(date='Saturday', temperature=22)]

weather.render({city:‘Manila’, description:’sunny’, thisWeek=week})

Shortcut from Views # views.py from django.shortcuts import render_to_response from mysite.models import MyModel

def list_view(request, template_name): m_list = MyModel.objects.filter(is_new=True) return render_to_response(template_name, {'m_list': m_list})

Templates

•  A text-based template for HTML, CSS, XML, JavaScript, etc.

•  Mixture between hard-coded text and abstractions

•  Abstractions – Variables – Tags

•  Re-useable and extensible

Hard-coded Text in weather.html <html>

<head> <title> Weather </title> </head>

<body> <p>Today’s weather in {{ city }} is {{ description }}.</p> <div id=“temperature”> {% for day in thisWeek %} <li> On {{ day.date }}, the temperature will be {{ day.temperature }}. </li> {% endfor %}

</div> <div id="ads"> {% block ads %} Click on these ads! {% endblock %} </div> </body> </html>

Variables

•  {{ variable }} –  If variable doesn’t exist, then output TEMPLATE_STRING_IF_INVALID (default: empty string “”)

•  {{ variable.attribute }} 1. Dictionary Lookup. variable[“attribute”] 2. Attribute Lookup. variable.attribute 3. Method Call. variable.attribute() 4. List-index Call. variable[attribute]

Variables in weather.html <html>

<head> <title> Weather </title> </head>

<body> <p>Today’s weather in {{ city }} is {{ description }}.</p> <div id=“temperature” {% for day in thisWeek %} <li> On {{ day.date }}, the temperature will be {{ day.temperature }}. </li> {% endfor %}

</div> <div id="ads"> {% block ads %} Click on these ads! {% endblock %} </div> </body> </html>

Filters •  Modify the output of variables •  {{ variable|filter }}

foo := “Hello World” bar := [‘a’, ‘b’, ‘c’]

{{ foo|lower }} --> hello world {{ bar|length }} --> 3 {{ bar|slice:“:2” }} --> [‘a’, ‘b’] {{ some|default:“error!” }} --> error!

Tags

•  for loops •  if clauses •  comments •  blocks •  and many more built-in tags (look them

up!)

•  {% tag %} … {% endtag %}

Tags in weather.html <html>

<head> <title> Weather </title> </head>

<body> <p>Today’s weather in {{ city }} is {{ description }}.</p> <div id=“temperature” {% for day in thisWeek %} <li> On {{ day.date }}, the temperature will be {{ day.temperature }}. </li> {% endfor %}

</div> <div id="ads"> {% block ads %} Click on these ads! {% endblock %} </div> </body> </html>

For loops {% for x in y %} … logic … {% endfor %}

fruit_basket := {‘apples’, ‘oranges’, ‘pineapples’}

{% for fruit in fruit_basket %} <li>{{ fruit }}</li>

{% endfor}

<li>apples</li> --> <li>orange</li> <li>pineapples</li>

If clauses

{% if <condition> %} … logic …

{% else %} … logic …

{% endif %}

{% if rain > 1 } Buy an umbrella for {{ price1 }} {% else %} Buy sunglasses for {{ price2 }} {% endif %}

Comments

{% comment %}

This comment won’t be displayed!

{% endcomment}

•  Ignore everything inside tag – For inline comments, use {# blah blah blah #}

Template Inheritance •  Define extensible parts of a template with

block tags {% block name %} … {% endblock %} •  Create child templates that can extend

blocks •  Load parent template with {% extends “parent_template” %}

weather.html <html>

<head> <title> Weather </title> </head>

<body> <p>Today’s weather in {{ city }} is {{ description }}.</p> <div id=“temperature”> {% for day in thisWeek %} <li> On {{ day.date }}, the temperature will be {{ day.temperature }}. </li> {% endfor %}

</div> <div id="ads"> {% block ads %} Click on these ads! {% endblock %} </div> </body> </html>

ads.html

{% extends "weather.html" %} {% block ads %} {% if rain > 1 } Buy an umbrella! {% else %} Buy sunglasses! {% endif %} {% endblock %}

Today’s weather in Manila is sunny.

•  On Thursday, the temperature will be 20. •  On Friday, the temperature will be 25. •  On Saturday, the temperature will be 22.

Click on these ads!

Buy an umbrella!

city  =  ‘Manila‘  descrip1on  =  'sunny‘  thisWeek  =  [dict(date='Thursday',temperature=20),                                              dict(date='Friday',  temperature=25),                                              dict(date='Saturday',  temperature=22)]  rain  =  3  

Context  

Displayed  by  browser  

Template Inheritance

•  In child template, redefine contents of the parent’s block tag – similar to overriding methods in class

inheritance •  If a block tag is not redefined, then use

contents of block tag in parent •  {{ block.super }} explicitly refers to

contents of block tag in parent

ads.html

{% extends "weather.html" %}

Questions?

71

Lab 3

•  Connect to the Postgresql Database server at 10.50.27.31

•  Create the models and the views for the mini social networking website FriendBook using Django

72

top related