You are on page 1of 82

Django: a high-level Python Web

framework that encourages rapid


development and clean,
pragmatic design.

On Freenode IRC: #python.tw


Speaker: timchen119 (aka. tim/ 使
徒提姆 )
 http://planet.python.org.tw/
Official
Python Planet@Taiwan -- 台灣 Python
愛好者的官方部落格星球
 http://www.python.org.tw/PotResources/
 Irc: Freenode #python.tw
 http://www.python.org.tw/PotPeople
Taiwan Community

 http://kalug.linux.org.tw/大高雄
Linux 使用者協會
 http://phorum.study-area.org/
 酷 ! 學園
 http://www.python.org.tw Python
台灣使 用者群組
 http://www.openfoundry.org/
 http://whoswho.openfoundry.org/for
 OSSF, 自由軟體鑄 造場 ,Who's Who
Web “Framework”?
A web application framework is a set
of software tools and libraries to
make it easier to create web
applications. They typically provide
functionality such as database
access, templating and session
management.
-- Wikipedia
• 開放原始碼的 Web應用框架。
• BSD 自由軟體版權釋出。
• Python寫成。
• 最初是被開發來用於管理勞倫斯出版集團
旗下的一些以新聞內容為主的網站。
• 命名由來 : 比利時的吉普賽爵士吉他手
Django Reinhardt。
• MVC的設計模式。
Django Project's History
 January 11, 2006 -- 0.91
 July 29, 2006 -- 0.95 ('magic-
removal')
 March 23, 2007 -- 0.96 (cleanup and
stabilization 0.95)
 September 3, 2008 -- 1.0 release.
 November 18, 2008 – 1.0.2 release
 March 23, 2009 – 1.1 beta
 April 2009 -- final 1.1 release
(planned)
Popular
Web Framework
 Java: Struts,Spring , WebWork, Tapestry, JSF
 PHP:Symfony,CakePHP , Code Igniter, Zend
Framework
 Perl: Catalyst,Maypole,Jifty
 Python:Django,TurboGears ,Pylons,web2py
 Ruby: Rails, Nitro,Merb
 Lua: Kepler,Orbit
MVC,MTV
 MVC: Model-View-Controller Architecture

MVC RoR Django


Model model model
View view template
Controller controller view
 MTV: Model-Template-View
HTTP
Request

Controller (Django’s
View)

View (Django’s
Template) Model
 Only add complexity when we have
strong benefit. (Do not create your
own Generic Factory’s Factory’s
Factory when you need hammer…)
 MVC Decoupling !
 Your HTML template separate your
model
 Your HTML template separate your
control logic
 Reuse your small logic components
 Great integration between
components
 Object-relational mapper (ORM)
 Automatic admin interface
 Elegant URL design
 Template system
 Cache system
 Internationalization
 ……
 Windows
 Instant Django
 (http://www.instantdjango.com/
)
 Notepad++
 Python 2.5.2
 Sqlite3
 Django 1.0
 http://kalug.linux.org.tw/~tim/cours
(http://tinyurl.com/djangotw)
 Database Wrapper -- model.py
 Admin Framework -- admin.py
 Controller -- view.py
 URL dispatcher -- url.py
 Template System -- index.html
 settings.py manage.py django-
admin.py are just helper.
• 下載 Instant Django (django.exe) 至 C:\
– 下載網址 http:// ti nyurl. com/djan go tw
• 雙擊解壓縮
• 點擊 start.bat
• 在提示符號 C:\django> 下打上
django-admin startproject myfirstproject
• 出現一個 myfirstproject 目錄
 cd myfirstproject (you could use tab
to type less)
 dir
 manage.py runserver
 Ctrl-C to break
 Browser: http://127.0.0.1:8000
 It worked ! Congratulations on
your first Django-powered page.
 python manage.py runserver 80
 python manage.py runserver
0.0.0.0:80
 ipconfig
 myfirstproject/
 __init__.py
 manage.py
 settings.py
 urls.py
 __init__.py:An empty file that tells
Python that this directory should be
considered a Python package.
 manage.py: A command-line utility
that lets you interact with this
Django project in various ways.
 settings.py: Settings/configuration
for this Django project.
 urls.py: The URL declarations for this
Django project; a "table of contents"
of your Django-powered site.
 本單元目的為熟悉環境之用,並練習修改
urls.py
 直接在 Project 底下開發 Helloworld 這個
程式
 start.bat
 cd c:\django\myfirstproject
 notepad++ urls.py
在 urls.py 裡加入一行 (r'^$',
'myfirstproject.helloworldapp.startpage'),
像這樣 :
urlpatterns = patterns('',
# Example:
# (r'^myfirstproject/', include('myfirstproject.foo.urls')),
# Uncomment the admin/doc line below and add
'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/',
include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# (r'^admin/(.*)', admin.site.root),
(r'^$', 'myfirstproject.helloworldapp.startpage'),
)
• notepad++ helloworldapp.py

from django.http import HttpResponse


def startpage(request):
return HttpResponse("Hello World!”)

• manage.py runserver 80
• http://127.0.0.1/
將 HttpResponse(“Hello World!”) 改成
你自己想要印出來的字串。
 Reload Browser 。
 毋須重啟 server 。
 Development Server 的特性。
 Django 的強項。
 Simple,Clean,Powerful ORM 。
 功能與容易使用程度的平衡性。
 透過 model 存取你的關聯性資料庫的資料

 由 model 自動生成資料庫 WEB 管理介面

 SQL friendly (but don’t really need
to.) 。
 cd c:\django
 django-admin startproject mysite
 django/mysite/
 __init__.py
 manage.py
 settings.py
 urls.py
 settings.py
 DATABASE_ENGINE : sqlite3
 DATABASE_NAME :
C:/django/sqldata.db
 always use forward slashes , Use /
not \ even in windows 。
 SQLite (do not need to change
DATABASE_HOST
DATABASE_PASSWORD
DATABASE_USER )
 django.contrib.auth -- An
authentication system.
 django.contrib.contenttypes -- A
framework for content types.
 django.contrib.sessions -- A session
framework.
 django.contrib.sites -- A framework
for managing multiple sites with one
Django installation.
 python manage.py syncdb
 looks at the INSTALLED_APPS setting
and creates any necessary database
tables according to the database
settings in your settings.py file.
 The syncdb command will only
create tables for apps in
INSTALLED_APPS.
 We just setup "project“
 Applications – app
 An app is a Web application that
does something
 A project is a collection of
configuration and apps for a
particular Web site.
 A project can contain multiple apps.
An app can be in multiple projects.
 python manage.py startapp polls
 polls/
 __init__.py
 models.py
 views.py
 一個簡單的投票程式 ( 這是 django
tutorial 裡的範例 )
 The first step in writing a database
Web app in Django is to define your
models
 simple poll app
 we'll create two models: polls and
choices
 Poll:
 Question
 publication date
 Choices
 Poll
 Choice
 votes
 from django.db import models
 class Poll(models.Model):
 question
=models.CharField(max_length=200)
 pub_date = models.DateTimeField('date
published')
 class Choice(models.Model):
 poll = models.ForeignKey(Poll)
 choice =
models.CharField(max_length=200)
 votes = models.IntegerField()
 INSTALLED_APPS
 Add 'mysite.polls‘
 python manage.py sql polls
 python manage.py syncdb
 settings.py:
 Add "django.contrib.admin" to your
INSTALLED_APPS setting.
 mysite/urls.py
 # Uncomment the next two lines to
enable the admin:
 from django.contrib import admin
 admin.autodiscover()
 # Uncomment the next line to enable
the admin: (r'^admin/(.*)',
admin.site.root),
 mysite/polls/admin.py
 from mysite.polls.models import Poll
 from django.contrib import admin
 admin.site.register(Poll)
 python manage.py syncdb
 Also create a superuser
 python manage.py createsuperuser
Django 動手作 單元 4

write a web announce system


 Object-relational mapper (ORM)
 Automatic admin interface
 Elegant URL design
 Designer-friendly Template system
Follow me. #1: Start
project
 django-admin startproject webann

webann/
__init__.py
manage.py
settings.py
urls.py
Follow me #2: Create
application
 cd webann
 python manage.py startapp
announce
webann/announce/
__init__.py
models.py
views.py
Follow me #3: Create
Database
 notepad++ settings.py
 DATABASE_ENGINE : sqlite3
 DATABASE_NAME :msg.db
 INSTALLED_APPS = 'announce'
 python manage.py syncdb
# also create a superuser
Follow me #4: build your
model
 webann/announce/models.py
from django.db import models #auto
generate
class Msg(models.Model):
name =
models.CharField(max_length=64)
date =
models.DateTimeField('postdate')
msgtxt =
Follow me #5: add admin
site
 notepad++
webann/announce/admin.py
 from webann.announce.models import
Msg
 from django.contrib import admin
 admin.site.register(Msg)
 settings.py:
 Add "django.contrib.admin" to your
INSTALLED_APPS setting.
 mysite/urls.py
 # Uncomment the next two lines to
Follow me #6: Write Your
Template
 Edit TEMPLATE_DIRS in your
settings.py
 Don’t put template in your www
directory.
 announce-
template/announce_list.html
<html><head><title>test</title></head
><body>
#(insert template code here)
Follow me #6: Write Your
Template (cont.)
{%if msgs_list %}
{% for msg in msgs_list %}
<p> {{ msg.name }} at {{msg.date}}
</p>
<p> {{msg.msgtxt}} </p>
{% endfor %}
{%else %}
<p>No Announce are available now.</p>
{%endif %}
Follow me #7: Write Your
View
webann/announce/views.py :
from django.shortcuts import
render_to_response
from superhard.announce.models import
Msg
def announce_index(request):
latest_msg =
Msg.objects.all().order_by('date')[:5]
return
Follow me #8: urls.py
(r'^$', 'announce.views.announce_index'),
('abc', 'announce.views.announce_index'),
 urlpatterns = patterns(
'webann.announce.views',
(r'^$', 'announce_index'),
('abc', 'announce_index'),
 django just need an urlpatterns object
#9: Let’s start play!
 python manage.py runserver
 python manage.py syncdb
 http://127.0.0.1:8000/
 http://127.0.0.1:8000/admin
Deploy
 Fastcgi or mod_python
 Static content should be separate
 Deploy on web hosting server not as
easy as PHP. (for now)
 But if it works, it works well !
 Lighttpd with fastcgi should be good.
Django 動手作單元 5
Object-Oriented
Database Shell
 Playing with the Model's API
 python manage.py shell
 from mysite.polls.models import Poll,
Choice
 Poll.objects.all()
 import datetime
 p = Poll(question="What's up?",
pub_date=datetime.datetime.now())
 p.save()
Playing With Model's API
 p.id
 p.question
 p.pub_date
 p.pub_date =
datetime.datetime(2007, 4, 1, 0, 0)
 p.save()
 Poll.objects.all()
Playing With Model's API

import datetime
# ...
class Poll(models.Model):
# ...
def was_published_today(self):
return self.pub_date.date() ==
datetime.date.today()
Playing With Model's API

class Poll(models.Model):
# ...
def __unicode__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
return self.choice
 Choice.__unicode__ = lambda self:
self.choice
Playing With Model's API
 Poll.objects.all()
 Poll.objects.filter(id=1)
 Poll.objects.filter(question__startswith
='What')
 Poll.objects.get(pub_date__year=200
7)
 Poll.objects.get(id=2)
 Poll.objects.get(pk=1)
 p = Poll.objects.get(pk=1)
 p.was_published_today()
Playing With Model's API
 p = Poll.objects.get(pk=1)
 p.choice_set.create(choice='Not
much', votes=0)
 p.choice_set.create(choice='The sky',
votes=0)
 c = p.choice_set.create(choice='Just
hacking again', votes=0)
 c.poll
 p.choice_set.all()
Quries → QuerySet (Lazy)
 filter
 exclude
 order_by
 distinct
 values
 ...
 QuerySet → Lazy
Quries → Not QuerySet
 get()
 create()
 get_or_create()
 count()
 .....
Django 講解單元 1: Poll

from django.conf.urls.defaults import *


urlpatterns = patterns('',
(r'^polls/$',
'mysite.polls.views.index'),
(r'^polls/(?P<poll_id>\d+)/$',
'mysite.polls.views.detail'),
(r'^polls/(?P<poll_id>\d+)/results/$',
'mysite.polls.views.results'),
(r'^polls/(?P<poll_id>\d+)/vote/$',
'mysite.polls.views.vote'),
Django 講解單元 1: Poll

from mysite.polls.models import Poll


from django.http import HttpResponse

def index(request):
latest_poll_list =
Poll.objects.all().order_by('-pub_date')
[:5]
output = ', '.join([p.question for p in
latest_poll_list])
return HttpResponse(output)
Django 講解單元 1: Poll
from django.template import Context, loader
from mysite.polls.models import Poll
from django.http import HttpResponse

def index(request):
latest_poll_list =
Poll.objects.all().order_by('-pub_date')[:5]
t = loader.get_template('polls/index.html')
c = Context({
'latest_poll_list': latest_poll_list,
})
return HttpResponse(t.render(c))
Django 講解單元 1: Poll

{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Django 講解單元 1: Poll

from django.shortcuts import


render_to_response
from mysite.polls.models import Poll

def index(request):
latest_poll_list =
Poll.objects.all().order_by('-pub_date')
[:5]
return
render_to_response('polls/index.html',
Django 講解單元 1: Poll

from django.http import Http404


# ...
def detail(request, poll_id):
try:
p = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise Http404
return
render_to_response('polls/detail.html'
, {'poll': p})
Django 講解單元 1: Poll

from django.shortcuts import


render_to_response,
get_object_or_404
# ...
def detail(request, poll_id):
p = get_object_or_404(Poll,
pk=poll_id)
return
render_to_response('polls/detail.html'
, {'poll': p})
Django 講解單元 1: Poll

<h1>{{ poll.question }}</h1>


<ul>
{% for choice in poll.choice_set.all %}
<li>{{ choice.choice }}</li>
{% endfor %}
</ul>
Django 講解單元 1: Poll

urlpatterns = patterns('',
(r'^polls/$',
'mysite.polls.views.index'),
(r'^polls/(?P<poll_id>\d+)/$',
'mysite.polls.views.detail'),
(r'^polls/(?P<poll_id>\d+)/results/$',
'mysite.polls.views.results'),
(r'^polls/(?P<poll_id>\d+)/vote/$',
'mysite.polls.views.vote'),
)
Django 講解單元 1: Poll

urlpatterns =
patterns('mysite.polls.views',
(r'^polls/$', 'index'),
(r'^polls/(?P<poll_id>\d+)/$',
'detail'),
(r'^polls/(?P<poll_id>\d+)/results/$',
'results'),
(r'^polls/(?P<poll_id>\d+)/vote/$',
'vote'),
)
Django 講解單元 1: Poll

urlpatterns =
patterns('mysite.polls.views',
(r'^$', 'index'),
(r'^(?P<poll_id>\d+)/$', 'detail'),
(r'^(?P<poll_id>\d+)/results/$',
'results'),
(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
)
Django 講解單元 1: Poll

A simple form

<h1>{{ poll.question }}</h1>

{% if error_message
%}<p><strong>{{
error_message }}</strong></p>{%
endif %}
Django 講解單元 1: Poll
<form action="vote/" method="post">
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice"
id="choice{{ forloop.counter }}"
value="{{ choice.id }}" />
<label for="choice{{
forloop.counter }}">{{ choice.choice
}}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
Django 講解單元 1: Poll

from django.shortcuts import


get_object_or_404,
render_to_response
from django.http import
HttpResponseRedirect
from django.core.urlresolvers import
reverse
from mysite.polls.models import
Choice, Poll
# ...
Django 講解單元 1: Poll

def vote(request, poll_id):


p = get_object_or_404(Poll, pk=poll_id)
try:
selected_choice =
p.choice_set.get(pk=request.POST['choice'
])
except (KeyError, Choice.DoesNotExist):
# Redisplay the poll voting form.
return
render_to_response('polls/detail.html', {
'poll': p,
'error_message': "You didn't select a
Django 講解單元 1: Poll

else:
selected_choice.votes += 1
selected_choice.save()
# Always return an
HttpResponseRedirect after successfully
dealing
# with POST data. This prevents data
from being posted twice if a
# user hits the Back button.
return
HttpResponseRedirect(reverse('mysit
e.polls.views.results', args=(p.id,)))
Django 講解單元 1: Poll

def results(request, poll_id):


p = get_object_or_404(Poll,
pk=poll_id)
return
render_to_response('polls/results.htm
l', {'poll': p})
Django 講解單元 1: Poll

<h1>{{ poll.question }}</h1>

<ul>
{% for choice in poll.choice_set.all %}
<li>{{ choice.choice }} --
{{ choice.votes }} vote{{
choice.votes|pluralize }}</li>
{% endfor %}
</ul>
Django 講解單元 1: Poll

from django.conf.urls.defaults import *

urlpatterns =
patterns('mysite.polls.views',
(r'^$', 'index'),
(r'^(?P<poll_id>\d+)/$', 'detail'),
(r'^(?P<poll_id>\d+)/results/$',
'results'),
(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
)
Django 講解單元 1: Poll

from django.conf.urls.defaults import *


from mysite.polls.models import Poll

info_dict = {
'queryset': Poll.objects.all(),
}
Django 講解單元 1: Poll
urlpatterns = patterns('',
(r'^$',
'django.views.generic.list_detail.object_list',
info_dict),
(r'^(?P<object_id>\d+)/$',
'django.views.generic.list_detail.object_detail',
info_dict),
url(r'^(?P<object_id>\d+)/results/$',
'django.views.generic.list_detail.object_detail',
dict(info_dict,
template_name='polls/results.html'),
'poll_results'),
(r'^(?P<poll_id>\d+)/vote/$',
Django Resource
 Django Official Site
 http://www.djangoproject.com/
 Official Django Document
 http://docs.djangoproject.com/en/1.0/conte
 Official Django Tutorial
 http://docs.djangoproject.com/en/1.0/intro/
 Django Step by Step ( 簡體中文 )
 http://www.woodpecker.org.cn/obp/django/
 Django Book
 http://www.djangobook.com/en/2.0/

You might also like