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 Model View Controller
RoR model view controller
Django model template 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 python
manage.py runserver 80 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 django/mysite/ __init__.py manage.py settings.py urls.py
mysite
settings.py DATABASE_ENGINE DATABASE_NAME :
: sqlite3
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 polls/
manage.py startapp polls
__init__.py models.py views.py
一個簡單的投票程式
tutorial 裡的範例 )
( 這是 django
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 python manage.py
sql polls 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. announcetemplate/announce_list.html
test #(insert template code here)
Follow me #6: Write Your Template (cont.) {%if msgs_list %} {% for msg in msgs_list %}
{{ msg.name }} at {{msg.date}}
{{msg.msgtxt}}
{% endfor %} {%else %}
No Announce are available now.
{%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 %}
{% for poll in latest_poll_list %} - {{ poll.question }}
{% endfor %}
{% else %}
No polls are available.
{% 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
{{ poll.question }}
{% for choice in poll.choice_set.all %} - {{ choice.choice }}
{% endfor %}
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
{{ poll.question }}
{% if error_message %}
<strong>{{ error_message }}
{% endif %}
Django 講解單元 1: Poll
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
{{ poll.question }}
{% for choice in poll.choice_set.all %} - {{ choice.choice }} -{{ choice.votes }} vote{{ choice.votes|pluralize }}
{% endfor %}
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
\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict), url(r'^(?P\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/