Professional Documents
Culture Documents
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
Django 100.00%
100.00%
URL 100.00%
100.00%
100.00%
Admin 100.00%
100.00%
URL 100.00%
99.74%
100.00%
100.00%
Django 100.00%
HTML 100.00%
86.16%
100.00%
django.contrib 99.72%
95.08%
100.00%
100.00%
100.00%
VCCDjango
http://djangobook.py3k.cn/2.0/
1/2
2010-5-5
http://djangobook.py3k.cn/2.0/
2/2
2010-5-5
Django
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | |
Django
DjangoWebWeb Django
Web
Web
Django Web Django
Web
Django framework
Django Django
Web
?
1
Django Web
Python
web
PythonWebCGI1998
PythonHTML.cgi
Python CGI10
#!/usr/bin/env python
import MySQLdb
print "ContentType: text/html\n"
print "<html><head><title>Books</title></head>"
print "<body>"
print "<h1>Books</h1>"
print "<ul>"
connection = MySQLdb.connect(user='me', passwd='letmein', db='my_db')
cursor = connection.cursor()
cursor.execute("SELECT name FROM books ORDER BY pub_date DESC LIMIT 10")
for row in cursor.fetchall():
print "<li>%s</li>" % row[0]
print "</ul>"
print "</body></html>"
djangobook.py3k.cn/2.0/chapter01/
1/6
2010-5-5
Django
connection.close()
CGIContent-Type HTML
HTML
HTML
16Python
16
latestbooks.cgi
1
CGI
Content-Type
WebPython
Web
Web Web
Django
MVC
Web
Django 4Python(models.py ,
views.py , urls.py ) html (latest_books.html )
# models.py (the database tables)
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=50)
pub_date = models.DateField()
djangobook.py3k.cn/2.0/chapter01/
2/6
2010-5-5
Django
models.py Python
(model)
Python SQL
views.py latest_books()
1
example.comhttp://example.com/latest/
latest_books()
latest_books.html html
Django
Django
DjangoDjango
djangobook.py3k.cn/2.0/chapter01/
3/6
2010-5-5
3
Django
CGI
1.
2.
3.
4. 2 1
5. 2-4
6.
Django
Django Kansas Lawrence
2003 Lawrence Journal-World Adrian Holovaty
Simon Willison Python
World Online ,
LJWorld.comLawrence.com KUsports.com
Adrian Simon
2005 World Online World
Online Jacob Kaplan-Moss
Django
World OnlineAdrian and JacobDjango
Django Django
6
Amazon.com, craigslist.orgwashingtonpost.com
Django Django
* * * * , Django
1
Django Django
Web Django
Django
Django
Django
1-12 Django
Django 1-78-11Django12
djangobook.py3k.cn/2.0/chapter01/
4/6
2010-5-5
Django
13-20Django
Django
http://www.djangoproject.com/
if while for
/
Web
Web
Python
Django Python Django
Python Django Python Django
1
Python ,Django
Django
API
Python
Python Python
Python http://docs.python.org/tut/ Mark Pilgrims
Django
Django 1.1
Django Django 1.11.21.31.9
1
Django2.02.0
1.03 Python python 2.0
python 2.6python3.0
1.1
Django,Django ,
:django,app ,db ,
DjangoDjango
http://www.djangoproject.com/r/django-users
Django,Django IRC channel Freenode
IRC network#django
djangobook.py3k.cn/2.0/chapter01/
5/6
2010-5-5
Django
Django
| | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter01/
6/6
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
:
WebDjango
DjangoPythonPython
Django /
12Django
Python
DjangoPythonPython
Python
Django2.32.62.32.6Python DjangoGIS
Python 2.42.6
Python,2.x 2.6
Django2.32.6PythonPython
Django
Python 2.3Python
Django Python 3.0
Python3.0Django Python3.0
PythonDjango
PythonPython 2.xPython 3.xPython
2.x
/ , python .
Python 2.4.1 (#2, Mar 31 2005, 00:05:10)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1666)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
, Python. http://www.python.org/download/
Django
Django
djangobook.py3k.cn/2.0/chapter02/
1/8
2010-5-5
Django
Django
1.0.31.1
http://www.djangoproject.com/download/
LinuxDjango
Django
Django1.0.2final.tar.gzDjango
setup.py installPython
Unix
1. tar xzvf Django*.tar.gz
2. cd Django*
3. sudo python setup.py install
Windows7-Zip(http://www.djangoproject.com/r/7zip/).tar.gz
DOS ShellDjango
Trunk
djangotrunk,djangosubversion
django
Subversion CVS Django Django
Subversion Django local checkout
Django Django
1
trunk djangotrunk
trunk
Django
Subversion http://subversion.tigris.org/
http://svnbook.red-bean.com/
Mac OS X 10.5SubversionDjango
svn version
djangobook.py3k.cn/2.0/chapter02/
2/8
2010-5-5
site-packages
site-packages
1
django.pthdjtrunk
/home/me/code/djtrunk
1. djtrunk/django/bin PATH djangoadmin.py
django-admin.py
.pth http://www.djangoproject.com/r/python/site-module/
Django bug
djtrunk svn update Subversion
http://code.djangoproject.com
trunktrunk Django
django
django django ``
djtrunk`` svn info Revision: (:) Django
Bug Django
[]Djano
Django
Django
ShellDjangopythonPython
django
>>> import django
>>> django.VERSION
(1, 1, 0, final', 1)
djangobook.py3k.cn/2.0/chapter02/
3/8
2010-5-5
Python (>>> )
(...
1
print value
>>> my_function('hello')
hello
Python Shell
djangowebdjangopython
web
project
Django
PostgreSQL (http://www.postgresql.org/)
SQLite 3 (http://www.sqlite.org/)
MySQL (http://www.mysql.com/)
Oracle (http://www.oracle.com/)
Django DjangoGIS
PostgreSQL
PostgreSQL
Python Python
SQLite python2.5
SQLite
Python2.5
djangobook.py3k.cn/2.0/chapter02/
4/8
2010-5-5
Windows python2.5
Django PostgreSQL
PostgreSQL http://www.djangoproject.com/r/python-pgsql/ psycopg
psycopg2 1
2
Windows PostgreSQL http://www.djangoproject.com/r/pythonpgsql/windows/ psycopg
Linuxpython-psycopg2psycopg2pythonpython-postgresql
Django SQLite 3
Python 2.5 Python
SQLite
2
Python2.4 SQLite 32
http://www.djangoproject.com/r/sqlite/pysqlitehttp://www.djangoproject.com/r/python-sqlite/
pysqlite2.0.3
Windows SQLite pysqlite
Linuxpython-sqlite3sqlite-python
pysqlite
Django MySQL
djangoMySQL4.0 3.X SQL
http://www.djangoproject.com/r/python-mysql/ MySQLdb
1
Linuxpython-mysql,python-mysqldb,mysplpython
DjangoOracle
djangoOracle9i
Oraclecx_Oracle,http://cx-oracle.sourceforge.net/ 4.3.1
5.0bug
Django
Django
Django
djangobook.py3k.cn/2.0/chapter02/
5/8
2010-5-5
()
pythondjangoproject
django
Django Django
Django /home/username/djcode/
djangolinuxdjangoadmin.pydjangoadmin
djangoadmin.py startproject ,
cd /usr/local/bindjangoadmin.pychmod +x djangoadmin.py
startproject 4
mysite/
__init__.py
manage.py
settings.py
urls.py
__init__.py Python ()
manage.py Django
djangobook.py3k.cn/2.0/chapter02/
6/8
2010-5-5
settings.py Django
Django
django
djangoweb
Web Apache
(cd mysite )
python manage.py runserver
Validating models...
0 errors found.
Django version 1.0, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROLC.
8000,
http://127.0.0.1:8000/ Django
django web
20 Django
Development Server
runserver 8000
IP
`` 0.0.0.0`` IP
python manage.py runserver 0.0.0.0:8000
IP
http://192.168.1.103:8000/ . (IP ) Unix
ifconfig Windows ipconfig
?
1
djangobook.py3k.cn/2.0/chapter02/
7/8
2010-5-5
Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter02/
8/8
2010-5-5
URL
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
URL
Django Django
Django
Hello world.
Hello worldhello.htmlHello
World
"Hello world" URL( http://www.example.com/hello.html ,
http://www.example.com/files/hello.html)
Django view function URL
URLconf Hello World
djangoadmin.py startprojectmysiteviews.py
Python Djangoview.py
view.py
Django
hello
hello_wonderful_beautiful_world Your First URLconf
djangobook.py3k.cn/2.0/chapter03/
1/13
2010-5-5
URL
Django
HttpResponseHello world
PythonHttpRequest
HttpResponsePythonDjango
URLconf
python manage.py runserverDjango
Hello world mysitehello
URL HTML
HTMLURLURLconf
1
URLconfDjango.
URLconf
from django.conf.urls.defaults import *
urlpatterns = patterns('',
)
django.conf.urls.defaultsDjango URLconf
patterns
patterns() urlpatterns patterns
djangobook.py3k.cn/2.0/chapter03/
2/13
2010-5-5
URL
) Python /usr/lib/python2.4/sitepackages/foo.py
PythonPython
>>> import sys
>>> print sys.path
URLpattern /hello/
DjangoURLURL(/) /hello/URL
(/)URL
djangobook.py3k.cn/2.0/chapter03/
3/13
2010-5-5
URL
(^)($)
$^hello//hello/
URL/hello/foo /hello/bar/hello/(^)
hello/$hello/URL/foo/bar/hello/hello/
^$hello/URL/foo/hello/bar
/hello/
URL^$
/hello/ URL
(/)URL (/)URL
URL settingAPPEND_SLASHD
URL/DjangoURL
APPEND_SLASHTrue. URLURL
APPEND_SLASHFalse,/URL.
hello Python (
) first-class objects
3
. (dot)
\d
[AZ]
A Z
[az]
a z
[AZaz]
a z
(, \d+ )
[^/]+
\d?
0 (, \d* 0 )
{1,3}
\d{1,3}
http://www.djangoproject.com/r/python/re-module/.
djangobook.py3k.cn/2.0/chapter03/
4/13
2010-5-5
URL
404
1
http://127.0.0.1:8000/404Django
URL URLconf
URL.
URL.
URL`` ^$`` , :
from mysite.views import hello, my_homepage_view
urlpatterns = patterns('',
('^$', my_homepage_view),
# ...
djangobook.py3k.cn/2.0/chapter03/
5/13
2010-5-5
URL
Django
Django.
http://127.0.0.1:8000/hello/Hello worldDjango
django-admin.py startprojectsettings.pyurls.pysettings.py
ROOT_URLCONFurls.py. settings.py
ROOT_URLCONF = 'mysite.urls'
mysite/urls.py
1
HttpRequest
HttpResponse Django
PythonHTTPbodyWeb Response
1. /hello/.
2. DjangoROOT_URLCONFURLconf.
3. DjangoURLconfURL/hello/
4.
5. HttpResponse
6. DjangoHttpResponseHTTP response Web page
Django-powered URLconfs
URLs URLs
Hello worldDjango
. /hello/HTML
1
.
Helloworld
djangobook.py3k.cn/2.0/chapter03/
6/13
2010-5-5
URL
HttpResponse python
pythondatetime
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2008, 12, 13, 14, 9, 39, 2731)
>>> print now
20081213 14:09:39.002731
Django Python
PythonDjango DjangoDjango
Django
Djangodatetime.datetime.now()
HttpResponse
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
1
helloview.pyhello
view.py
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)
views.py
import datetime
datetime.datetime now
Python format-string HTML
%snow%s%s
datetime.datetime%s
2008-12-13 14:09:39.002731HTMLIt is now 2008-12-13 14:09:39.002731
HTML
helloHttpResponse
djangobook.py3k.cn/2.0/chapter03/
7/13
2010-5-5
URL
urls.pyURLDjangoURL /time/
current_datetime URL
URL/time/
URLconfpython manage.py runserver
http://127.0.0.1:8000/time/
Django
1
Django
America/Chicago Django/
settings.py
URL
DjangoURL
DjangoURL DjangoURL
URL
URLconf
URL
1
/time/plus/1/
1 /time/plus/2/ 2 /time/plus/3/ 3
djangobook.py3k.cn/2.0/chapter03/
8/13
2010-5-5
URL
URL
urlpatterns = patterns('',
('^time/$', current_datetime),
('^time/plus/1/$', one_hour_ahead),
('^time/plus/2/$', two_hours_ahead),
('^time/plus/3/$', three_hours_ahead),
('^time/plus/4/$', four_hours_ahead),
2
)
234 5
URL
URL
webPHPJava
/time/plus?hours=3hours
Django ( Django
URL URL /time/plus/3/
URLWeb
DjangoURLURL
wildcard URLpatterns
URLd+1
urlpatterns = patterns('',
# ...
(r'^time/plus/\d+/$', hours_ahead),
# ...
)
# URL
URL /time/plus/2/ , /time/plus/25/ , /time/plus/100000000000/ URL
99
\d{1,2} :
(r'^time/plus/\d{1,2}/$', hours_ahead),
Web
99
3
r Python
Pythonn
rPythonn
nPythonPython
URL
djangobook.py3k.cn/2.0/chapter03/
9/13
2010-5-5
URL
URL
URL
\d{1,2}
(r'^time/plus/(\d{1,2})/$', hours_ahead),
URLconf
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),
)
hours_ahead
URLpattern
URLpattern
URL
URL
()
hours_ahead current_datetime
view
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)
HttpRequest ()
djangobook.py3k.cn/2.0/chapter03/
10/13
2010-5-5
URL
offset URL URL/time/plus/3/offset3
URL/time/plus/21/offset21string
integer21
Unicode objectsPython
offset Python
( request
offset int() .
int()PythonValueError
int(foo)ValueErrordjango.http.Http404
404
URL(d{1,2})
offset URLpattern
ValueError
/ current_datetime
datetime.datetime.now()/
datetime.timedeltadatetime.datetime dt
offsetint()datetime.timedeltahours
Python
%s (offset, dt)
HTMLHttpResponse
URLDjango
http://127.0.0.1:8000/time/plus/3/ http://127.0.0.1:8000/time/plus/5/
http://127.0.0.1:8000/time/plus/24/ http://127.0.0.1:8000/time/plus/100/
URL Django Page not found error ,
404 URL http://127.0.0.1:8000/time/plus/ ( ) 404
Django
Web views.py
Python hours_ahead offset = int(offset)
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)
djangobook.py3k.cn/2.0/chapter03/
11/13
2010-5-5
URL
return HttpResponse(html)
/time/plus/3/ TypeError
"unsupported type for timedelta hours component: unicode" .
datetime.timedelta hours offset
datetime.timedelta TypeError
Django
( "unsupported type"
Python Python
Django
()
Local vars
djangobook.py3k.cn/2.0/chapter03/
12/13
2010-5-5
URL
HTML
Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter03/
13/13
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
HTML
Python
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
HTML
Python Python
Python
Python HTML
HTML/CSSPython
Python
Python HTML
Python Django
(Template System)
HTMLDjango
HTML
<html>
<head><title>Ordering notice</title></head>
<body>
<h1>Ordering notice</h1>
<p>Dear {{ person_name }},</p>
<p>Thanks for placing an order from {{ company }}. It's scheduled to
ship on {{ ship_date|date:"F j, Y" }}.</p>
<p>Here are the items you've ordered:</p>
djangobook.py3k.cn/2.0/chapter04/
1/25
2010-5-5
<ul>
{% for item in item_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% if ordered_warranty %}
<p>Your warranty information will be included in the packaging.</p>
{% else %}
<p>You didn't order a warranty, so you're on your own when
the products inevitably stop working.</p>
{% endif %}
<p>Sincerely,<br />{{ company }}</p>
</body>
</html>
HTML
{{ person_name }} (variable)
( {% if ordered_warranty %} ) (template tag) (tag)
for {% for item in item_list %} if
{% if ordered_warranty %}
forPythonfor if
tagordered_warrantyTrue{% if
ordered_warranty %}{% else %}{% else %}{% endif %}{% else %}
filter
{{ship_date|date:F j, Y }}ship_datedateF
j,Ydate (|)Unix
Django tagsfilters,. Ftagsfilters,
. tagfilters9
PythonDjango
PythonDjango
1. Template Django
Template ;
2. rendercontext
context
djangobook.py3k.cn/2.0/chapter04/
2/25
2010-5-5
Python
Pythonpython manage.py shellpython
manage.py shell Django
DjangoDjango
DjangoDJANGO_SETTINGS_MODULE
settings.pymysitePython
DJANGO_SETTINGS_MODULEmysite.settings
python manage.py shellDJANGO_SETTINGS_MODULE
`` python manage.py shell``
Template
Template() TemplateSyntaxError
>>> from django.template import Template
>>> t = Template('{% notatag %}')
djangobook.py3k.cn/2.0/chapter04/
3/25
2010-5-5
t.render(c)UnicodePython
u DjangoUnicode
Django
DjangoUnicode
A-Z
Contexts
Python Context Context
A-Za-z
djangobook.py3k.cn/2.0/chapter04/
4/25
2010-5-5
...
... <p>Thanks for placing an order from {{ company }}. It's scheduled to
... ship on {{ ship_date|date:"F j, Y" }}.</p>
...
... {% if ordered_warranty %}
... <p>Your warranty information will be included in the packaging.</p>
... {% else %}
... <p>You didn't order a warranty, so you're on your own when
... the products inevitably stop working.</p>
... {% endif %}
...
... <p>Sincerely,<br />{{ company }}</p>"""
>>> t = Template(raw_template)
>>> import datetime
>>> c = Context({'person_name': 'John Smith',
...
...
...
'ordered_warranty': False})
>>> t.render(c)
u"<p>Dear John Smith,</p>\n\n<p>Thanks for placing an order from Outdoor
Equipment. It's scheduled to\nship on April 2, 2009.</p>\n\n\n<p>You
didn't order a warranty, so you're on your own when\nthe products
inevitably stop working.</p>\n\n\n<p>Sincerely,<br />Outdoor Equipment
</p>"
t raw_template Template
Python datetime
Context c Context Python
person_name 'John Smith' , company Outdoor Equipment
render() context
context
>>> from django.template import Template, Context
>>> t = Template('Hello, {{ name }}')
djangobook.py3k.cn/2.0/chapter04/
5/25
2010-5-5
context render()
# Bad
for name in ('John', 'Julie', 'Pat'):
t = Template('Hello, {{ name }}')
print t.render(Context({'name': name}))
# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
print t.render(Context({'name': name}))
Django
XML XML Django
context datetime.date
listdictionary
Django (.)
Python
(dots)
djangobook.py3k.cn/2.0/chapter04/
6/25
2010-5-5
* *
{{ items.1 }} `` TemplateSyntaxError``
Python
Python0 01
foo["bar"] )
( foo.bar )
foo.bar() )
( foo[bar] )
{{person.name.upper}}
person['name'] ) upper() ):
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')
djangobook.py3k.cn/2.0/chapter04/
7/25
2010-5-5
silent_variable_failure
True :
>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
...
...
def first_name(self):
raise AssertionError, "foo"
>>> p = PersonClass3()
>>> t.render(Context({"person": p}))
Traceback (most recent call last):
...
AssertionError: foo
>>> class SilentAssertionError(AssertionError):
...
silent_variable_failure = True
def first_name(self):
raise SilentAssertionError
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
u'My name is .'
BankAccount delete()
{{ account.delete }} `` account`` BankAccount
account
alters_data
def delete(self):
# Delete the account
delete.alters_data = True
{{ account.delete }} delete() delete() alters_data=True
delete()
>>> from django.template import Template, Context
>>> t = Template('Your name is {{ name }}.')
>>> t.render(Context())
u'Your name is .'
>>> t.render(Context({'var': 'hello'}))
u'Your name is .'
djangobook.py3k.cn/2.0/chapter04/
8/25
2010-5-5
web
(context)
(full populated) Context() (Context)
Python(syntax)``(Context)`` :
1
if/else
{% if %} (evaluate)
{% if %} {% endif %}
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% endif %}
{% else %}
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% else %}
<p>Get back to work.</p>
{% endif %}
Python
PythonDjangoFalse
([] )
djangobook.py3k.cn/2.0/chapter04/
9/25
2010-5-5
(() )
({} )
('' )
(0 )
None
False
(python)
`` True``
1
{% if athlete_list and coach_list or cheerleader_list %}
{% if %}
{% if athlete_list %}
{% if coach_list or cheerleader_list %}
We have athletes, and either coaches or cheerleaders!
{% endif %}
{% endif %}
1
{% if athlete_list or coach_list or parent_list or teacher_list %}
djangobook.py3k.cn/2.0/chapter04/
10/25
2010-5-5
{% elif %} `` {% if %}``
{% if athlete_list %}
<p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
<p>No athletes are available.</p>
{% if coach_list %}
<p>Here are the coaches: {{ coach_list }}.</p>
{% endif %}
{% endif %}
{% endif %} {% if %}
for
{% for %} Python for for X in Y Y
X {% for %}
{% endfor %}
athlete_list
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
reversed
{% for athlete in athlete_list reversed %}
...
{% endfor %}
{% for %}
{% for athlete in athlete_list %}
<h1>{{ athlete.name }}</h1>
<ul>
{% for sport in athlete.sports_played %}
<li>{{ sport }}</li>
{% endfor %}
</ul>
{% endfor %}
{% if athlete_list %}
{% for athlete in athlete_list %}
<p>{{ athlete.name }}</p>
{% endfor %}
{% else %}
<p>There are no athletes. Only computer programmers.</p>
{% endif %}
djangobook.py3k.cn/2.0/chapter04/
11/25
2010-5-5
{% empty %}
<p>There are no athletes. Only computer programmers.</p>
{% endfor %}
Django
Djangocontinue
forloop.counter 1
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
forloop.counter0 forloop.counter 0
0
forloop.revcounter forloop.revcounter
1
forloop.revcounter0 forloop.revcounter 0
1
1
forloop.first ````
|
{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
Favorite places:
{% for p in places %}{{ p }}{% if not forloop.last %}, {% endif %}{% endfor %}
forloop.parentloop forloop
djangobook.py3k.cn/2.0/chapter04/
12/25
2010-5-5
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
forloop {% endfor %} forloop
Contextforloop
{% for %} forloop Django
forloop.parentloop forloop
{% for %} forloop.parentloop
ifequal/ifnotequal
DjangoPython
Django {% ifequal %}
{% ifequal %} {% ifequal %} {% endifequal %}
user currentuser :
{% ifequal user currentuser %}
<h1>Welcome!</h1>
{% endifequal %}
{% if %} {% ifequal %} {% else%}
{% ifequal section 'sitenews' %}
<h1>Site News</h1>
{% else %}
<h1>No News Here</h1>
{% endifequal %}
{% ifequal %}
{% ifequal variable 1 %}
{% ifequal variable 1.23 %}
{% ifequal variable 'foo' %}
{% ifequal variable "foo" %}
Python {% ifequal %}
djangobook.py3k.cn/2.0/chapter04/
13/25
2010-5-5
{% if %} {% ifequal %}
HTMLPythonDjango {# #}
{# This is a comment #}
This is a {# this is not
a comment #}
test.
1
`` {% comment %}``
{% comment %}
This is a
multiline comment.
{% endcomment %}
{{ name|lower }}
{{ name }} lower
* *
{{ my_list|first|upper }}
{{ bio|truncatewords:"30" }}
bio 30
F
addslashes : JavaScript
djangobook.py3k.cn/2.0/chapter04/
14/25
2010-5-5
F
length :
Python
__len__()
Django
Python
Python
Django Django
FULL-StackWeb Django
Python
Django
Django World Online
Django
Django Python
Django
Python
HTML Dreamweaver
Django
HTML
Python
Python
Python
Python
djangobook.py3k.cn/2.0/chapter04/
15/25
2010-5-5
mysite.views
current_datetime
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
Django
from django.template import Template, Context
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
t = Template("<html><body>It is now {{ current_date }}.</body></html>")
html = t.render(Context({'current_date': now}))
return HttpResponse(html)
Python
Python
/home/djangouser/templates/mytemplate.html :
from django.template import Template, Context
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
# Simple way of using templates from the filesystem.
# This is BAD because it doesn't account for missing files!
fp = open('/home/djangouser/templates/mytemplate.html')
t = Template(fp.read())
fp.close()
html = t.render(Context({'current_date': now}))
return HttpResponse(html)
mytemplate.html open()
IOError
open() fp.read() fp.close()
djangobook.py3k.cn/2.0/chapter04/
16/25
2010-5-5
Django API
API
ROOT_URLCONF settings.py
settings.pyTEMPLATE_DIRS
tuple
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
Django
TEMPLATE_DIRS
TEMPLATE_DIRS = (
'/home/django/mysite/templates',
)
Web
Django templates
mysite
TEMPLATE_DIRS
Bad:
2
# Missing comma!
TEMPLATE_DIRS = (
'/home/django/mysite/templates'
)
Good:
# Comma correctly in place.
TEMPLATE_DIRS = (
'/home/django/mysite/templates',
)
Python
1
Windows Unix/,
TEMPLATE_DIRS = (
'C:/www/django/templates',
)
Django Python TEMPLATE_DIRS
djangobook.py3k.cn/2.0/chapter04/
17/25
2010-5-5
import os.path
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
1
TEMPLATE_DIRS Django
current_datetime
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
t = get_template('current_datetime.html')
html = t.render(Context({'current_date': now}))
return HttpResponse(html)
django.template.loader.get_template()
get_template()
Template
current_datetime.html.html
get_template() TEMPLATE_DIRS
TEMPLATE_DIRS '/home/django/mysite/templates'
get_template() /home/django/mysite/templates/current_datetime.html
get_template() TemplateDoesNotExist
Django python manage.py runserver
Django current_datetime
http://127.0.0.1:8000/time/ DEBUG True current_datetime.html
Django TemplateDoesNotExist
djangobook.py3k.cn/2.0/chapter04/
18/25
2010-5-5
4-1:
Django
current_datetime.html
<html><body>It is now {{ current_date }}.</body></html>
render_to_response()
ContextHttpResponse
get_template()
Django
HttpResponse
django.shortcuts render_to_response()
``\ ``````
System Message: WARNING/2 (<string>, line 1736); backlink
Inline literal start-string without end-string.
System Message: WARNING/2 (<string>, line 1736); backlink
Inline literal start-string without end-string.
System Message: WARNING/2 (<string>, line 1736); backlink
Inline literal start-string without end-string.
render_to_response() current_datetime
from django.shortcuts import render_to_response
import datetime
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})
get_template Template Context HttpResponse
django.shortcuts.render_to_response import datetime .
djangobook.py3k.cn/2.0/chapter04/
19/25
2010-5-5
current_datetime now
HttpResponse render_to_response() render_to_response()
HttpResponse return
render_to_response()
Context render_to_response()
locals()
current_datetime :
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})
now
Python locals()
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response('current_datetime.html', locals())
context locals()
now current_date
locals()
locals()
locals() request
get_template()
Django
get_template()
t = get_template('dateapp/current_datetime.html')
djangobook.py3k.cn/2.0/chapter04/
20/25
2010-5-5
include
{% include %}
/
{% include %}
nav.html /
{% include 'nav.html' %}
{% include "nav.html" %}
includes/nav.html :
{% include 'includes/nav.html' %}
template_name
{% include template_name %}
get_template() TEMPLATE_DIRS
context
# mypage.html
<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>
# includes/nav.html
<div id="nav">
You are in: {{ current_section }}
</div>
current_section mypage.html
include
1
{% include %}Django
DEBUG True Django TemplateDoesNotExist
DEBUG False
HTML Django
HTML Web
djangobook.py3k.cn/2.0/chapter04/
21/25
2010-5-5
includes HTML
Django {% include %} Django
current_datetime.html current_datetime
hours_ahead
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>Future time</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
<hr>
<p>Thanks for visiting my site.</p>
</body>
</html>
HTML
JavaScript HTML
include
include header.html
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
footer.html :
<hr>
<p>Thanks for visiting my site.</p>
</body>
</html>
djangobook.py3k.cn/2.0/chapter04/
22/25
2010-5-5
include
<h1>My helpful timestamp site</h1> header.html
<title> <h1> <title>
Django include
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>
base.html HTML
template
base.html .
{% block %} {% block %}
{% block %}
current_datetime.html
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
hours_ahead
{% extends "base.html" %}
{% block title %}Future time{% endblock %}
{% block content %}
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
{% endblock %}
base.html
current_datetime.html {% extends %}
djangobook.py3k.cn/2.0/chapter04/
23/25
2010-5-5
base.html
base.html {% block %} block
{ block title %} {% block content %}
{% block title %} {% block content %}
footer {% block %}
1. base.html
2. base_SECTION.html (, base_photos.html base_forum.html )
base.html
3.
{% extends %}
{% block %}
{% block %}
{{ block.super }}
{% block %} block
block
{% block %}
{% extends %} get_template()
TEMPLATE_DIRS
{% extends %}
djangobook.py3k.cn/2.0/chapter04/
24/25
2010-5-5
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter04/
25/25
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
5
Django URLConf
Web
Web
Amazon.com
HTML
Python Django
Django
Django
SQL
HTML HTML
Python SQL
MySQLdb http://www.djangoproject.com/r/python-mysql/
MySQL
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})
Django
djangobook.py3k.cn/2.0/chapter05/
1/19
2010-5-5
MTV
Django Web
Django
Model-View-Controller
(MVC) Model View
Controller
MVC
MVC
Django MVC MVC Django MV C
M django
1
V
C Django URLconf URL
Python
C Django Model(Template)Views
Django MTV MTV
M Model
djangobook.py3k.cn/2.0/chapter05/
2/19
2010-5-5
T (Template)
V View
Django
Django
CREATE DATABASE
SQLiteSQLite
TEMPLATE_DIRS Django settings.py
DATABASE_ENGINE = ''
DATABASE_NAME = ''
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
Table 5-1
5-1.
`` postgresql``
PostgreSQL
postgresql_psycopg2
PostgreSQL
mysql
M ySQL
MySQLdb , http://www.djangoproject.com/r/python-mysql/.
sqlite3
SQLite
oracle
Oracle
cx_Oracle , http://www.djangoproject.com/r/python-oracle/.
5-1
Linux
`` python-postgresql`` `` python-psycopg``
djangobook.py3k.cn/2.0/chapter05/
3/19
2010-5-5
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_NAME Django
DATABASE_NAME = 'mydb'
SQLite
DATABASE_NAME = '/home/django/mydata.db'
SQLite/home/django
DATABASE_USER Django SQLite
DATABASE_PASSWORD Django SQLite
DATABASE_HOST Django Django
SQLite
MySQL MySQL '/' MySQL
Unix socket
DATABASE_HOST = '/var/run/mysql'
1
`` mysite``
`` python manage.py shell`` `` manager.py shell``
DjangoPython Django
5-2
5-2.
`` DATABASE_ENGINE`` 5-1
DATABASE_ENGINE setting
yet.
Environment variable
`` python manager.py shell`` `` python``
DJANGO_SETTINGS_MODULE
is undefined.
Error loading _____ module:
No module named _____.
_____ isnt an available
database backend.
DATABASE_ENGINE
`` DATABASE_USER``
DATABASE_HOSTDATABASE_PORT
djangobook.py3k.cn/2.0/chapter05/
4/19
2010-5-5
Django app-Django
PythonDjango
project , project app
projectDjango app
project, app
TEMPLATE_DIRS
appDjangoPython
Djangoapp app
projectproject
Django Web
app
app
app
views.pyURLconf
apps
app Django Django app
apps app
`` mysite`` `` books`` app
python manage.py startapp books
mysite books
books/
__init__.py
models.py
tests.py
views.py
app
models.py views.py models.py
importDjango app
Python
MTVM DjangoPython
CREATE TABLE Python SQL
DjangoSQLPython Django
SQL
Python SQL Django
djangobook.py3k.cn/2.0/chapter05/
5/19
2010-5-5
API Django
Python
-
Django
MySQL,
PythonPython
/ SQLPython
SQL
SQL EmailURL
Django
SQL WebPython
MySQL, PostgreSQL, and SQLiteCREATE TABLE
Python Django
,Django
18
//
SQL
[many-to-many]
[one-to-many][foreign key]
Python `` startapp`` models.py
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
djangobook.py3k.cn/2.0/chapter05/
6/19
2010-5-5
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
django.db.models.Model
Model
Django
CharField varchar Publisher
Django
B
Django
Djangoid
Django
books app
settings.py INSTALLED_APPS INSTALLED_APPS Django app
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
djangobook.py3k.cn/2.0/chapter05/
7/19
2010-5-5
'django.contrib.sites',
# app
MIDDLEWARE_CLASSES
INSTALLED_APPSapps `` mysite.books`` `` INSTALLED_APPS``
MIDDLEWARE_CLASSES = (
# 'django.middleware.common.CommonMiddleware',
# 'django.contrib.sessions.middleware.SessionMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
)
INSTALLED_APPS = (
# 'django.contrib.auth',
# 'django.contrib.contenttypes',
# 'django.contrib.sessions',
# 'django.contrib.sites',
'mysite.books',
)
(TEMPLATE_DIRSINSTALLED_APPS
tuple
)
'mysite.books' books app INSTALLED_APPS app Python
.
python manage.py validate
validate 0 errors found
python manage.py validate
djangobook.py3k.cn/2.0/chapter05/
8/19
2010-5-5
)
;
CREATE TABLE "books_book" (
"id" serial NOT NULL PRIMARY KEY,
"title" varchar(100) NOT NULL,
"publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFER
"publication_date" date NOT NULL
)
;
CREATE TABLE "books_book_authors" (
"id" serial NOT NULL PRIMARY KEY,
"book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED,
"author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED,
UNIQUE ("book_id", "author_id")
)
;
CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id");
COMMIT;
sqlall SQLDjango
SQLUnix
`` python manager.py sqlall books | psql mydb`` Django
SQL `` syncdb``
python manage.py syncdb
syncdb
djangobook.py3k.cn/2.0/chapter05/
9/19
2010-5-5
syncdb
SQLDjango
PostgreSQL`` psql`` `` python manage.py dbshell``
`` DATABASE_SERVER``
...
website='http://www.apress.com/')
>>> p1.save()
>>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',
...
...
website='http://www.oreilly.com/')
>>> p2.save()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]
Publisher
`` Publisher`` `` name, address``
save() Django INSERT
`` Publisher.objects``
`` Publisher.objects.all()`` `` Publisher``
DjangoSQL `` SELECT``
Django modle API
Django`` save()``
1
p1 = Publisher(...)
# At this point, p1 is not saved to the database yet!
p1.save()
# Now it is.
`` objects.create()``
>>> p1 = Publisher.objects.create(name='Apress',
...
...
djangobook.py3k.cn/2.0/chapter05/
10/19
2010-5-5
...
website='http://www.apress.com/')
>>> p2 = Publisher.objects.create(name="O'Reilly",
...
...
...
website='http://www.oreilly.com/')
DjangoAPI
publisher````
System Message: WARNING/2 (<string>, line 872); backlink
Inline literal start-string without end-string.
System Message: WARNING/2 (<string>, line 872); backlink
Inline literal start-string without end-string.
[<Publisher: Publisher object>, <Publisher: Publisher object>]
__unicode__()
Publisher Book __unicode__() Author __unicode__()
djangobook.py3k.cn/2.0/chapter05/
11/19
2010-5-5
first_namelast_name
__unicode__()unicode `` __unicode__()`` Unicode
Python`` TypeError`` coercing to
Unicode: need string or buffer, int found
Unicode
Unicode
unicodePythonLatin
Latin
pythonASCIIISO-8859-1UTF-8
1280-9A-ZASCII
Python
??? ??????
UnicodeUnicode Python
Unicode
Django Unicode
Unicode Unicode Unicode
Unicode
http://www.joelonsoftware.com/articles/Unicode.html
Python Shell python manage.py shell
`` Publisher``
>>> from books.models import Publisher
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Apress>, <Publisher: O'Reilly>]
__unicode__() Django
__unicode__()
1
__unicode__() Django
__unicode__()
>>> p = Publisher(name='Apress',
...
...
...
state_province='CA',
...
country='U.S.A.',
djangobook.py3k.cn/2.0/chapter05/
12/19
2010-5-5
...
website='http://www.apress.com/')
`` save()``
>>> p.save()
SQL
INSERT INTO books_publisher
(name, address, city, state_province, country, website)
VALUES
('Apress', '2855 Telegraph Ave.', 'Berkeley', 'CA',
'U.S.A.', 'http://www.apress.com/');
Publisher id save()
>>> p.id
52
# this will differ based on your own data
save() SQL
UPDATE books_publisher SET
name = 'Apress Publishing',
address = '2855 Telegraph Ave.',
city = 'Berkeley',
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 52;
Web
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
SQL
SELECT id, name, address, city, state_province, country, website
FROM books_publisher;
djangobook.py3k.cn/2.0/chapter05/
13/19
2010-5-5
Django SELECT*
SELECT* Python
objects 10
objects
all()
list QuerySet C
QuerySet
Django API
`` filter()``
>>> Publisher.objects.filter(name='Apress')
[<Publisher: Apress>]
filter() WHERE SQL
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = 'Apress';
filter()
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")
[<Publisher: Apress>]
AND SQL
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = 'U.S.A.'
AND state_province = 'CA';
SQL =
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
djangobook.py3k.cn/2.0/chapter05/
14/19
2010-5-5
icontains(LIKE),startswithendswith, range(SQLBETWEEN
C
`` filter()``
`` get()``
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
QuerySet)
>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
...
MultipleObjectsReturned: get() returned more than one Publisher
it returned 2! Lookup parameters were {'country': 'U.S.A.'}
>>> Publisher.objects.get(name="Penguin")
Traceback (most recent call last):
...
DoesNotExist: Publisher matching query does not exist.
try:
p = Publisher.objects.get(name='Apress')
except Publisher.DoesNotExist:
print "Apress isn't in the database yet."
else:
print "Apress is in the database."
Django
order_by()
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]
all() SQL
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name;
djangobook.py3k.cn/2.0/chapter05/
15/19
2010-5-5
>>> Publisher.objects.order_by("address")
[<Publisher: O'Reilly>, <Publisher: Apress>]
>>> Publisher.objects.order_by("state_province")
[<Publisher: Apress>, <Publisher: O'Reilly>]
>>> Publisher.objects.order_by("name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
order_by()
Django
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
**class Meta:**
**ordering = ['name']**
>>> Publisher.objects.filter(country="U.S.A.").order_by("name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
djangobook.py3k.cn/2.0/chapter05/
16/19
2010-5-5
Python
>>> Publisher.objects.order_by('name')[0]
<Publisher: Apress>
Pythonrange-slicing
>>> Publisher.objects.order_by('name')[0:2]
SQL
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name
OFFSET 0 LIMIT 2;
Python(negative slicing)
>>> Publisher.objects.order_by('name')[1]
Traceback (most recent call last):
...
AssertionError: Negative indexing is not supported.
order_by()
>>> Publisher.objects.order_by('name')[0]
save()
SQL
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = 'Apress';
UPDATE books_publisher SET
name = 'Apress Publishing',
address = '2855 Telegraph Ave.',
city = 'Berkeley',
djangobook.py3k.cn/2.0/chapter05/
17/19
2010-5-5
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 52;
ApressID52
Djangosave()name
namename
QuerySetupdate()
>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')
SQL
UPDATE books_publisher
SET name = 'Apress Publishing'
WHERE id = 52;
update()QuerySet
PublishercountryU.S.AUSA
>>> Publisher.objects.all().update(country='USA')
2
update() 2
delete()
>>> p = Publisher.objects.get(name="O'Reilly")
>>> p.delete()
>>> Publisher.objects.all()
[<Publisher: Apress Publishing>]
delete()update()
>>> Publisher.objects.filter(country='USA').delete()
>>> Publisher.objects.all().delete()
>>> Publisher.objects.all()
[]
Django
all()
>>> Publisher.objects.delete()
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Manager' object has no attribute 'delete'
all()
>>> Publisher.objects.all().delete()
all()
djangobook.py3k.cn/2.0/chapter05/
18/19
2010-5-5
>>> Publisher.objects.filter(country='USA').delete()
Django
Django
Web
Django
the GNU Free Document License Hosting graciously provided by
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter05/
19/19
2010-5-5
Admin
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Django
Django Django
Django
adminDjango
admin
django.contrib
Djangodjango.contribdjango.contribDjango
Django(add-on) django.contrib
Python Django
django.contribdjango.contrib.admin
django.contrib(django.contrib.auth)
(django.contrib.sessioins)(django.contrib.comments)
Djangodjango.contrib Django
django.contrib
Django
settings
1. 'django.contrib.admin'settingINSTALLED_APPS INSTALLED_APPS
,
2. INSTALLED_APPS
'django.contrib.auth''django.contrib.contenttypes''django.contrib.sessions'Django
djangobook.py3k.cn/2.0/chapter06/
1/15
2010-5-5
Admin
3 (mysite
INSTALLED_APPS)
3. MIDDLEWARE_CLASSES 'django.middleware.common.CommonMiddleware'
'django.contrib.sessions.middleware.SessionMiddleware'
'django.contrib.auth.middleware.AuthenticationMiddleware' (mysite
)
python manage.py syncdb
'django.contrib.auth'INSTALLED_APPSsyncdb,
python manage.py createsuperuseradmin
admin (: INSTALLED_APPS
'django.contrib.auth'python manage.py createsuperuser.)
adminURLconf(urls.py). djangoadmin.py startproject
urls.pyDjango admin
6-1
djangobook.py3k.cn/2.0/chapter06/
2/15
2010-5-5
Admin
6-1. Django
`` python manage.py
createsuperuser``
-(Groups)
(Users)
Django
`` django.middleware.locale.LocaleMiddleware`` ``
MIDDLEWARE_CLASSES``
django.contrib.sessions.middleware.SessionMiddleware* *
Change passwordLog outGroupsUsers Django
Django
djangobook.py3k.cn/2.0/chapter06/
3/15
2010-5-5
Admin
UersChange
6-3.
`` SELECT * FROM
auth_user;``
djangobook.py3k.cn/2.0/chapter06/
4/15
2010-5-5
Admin
6-4.
change
password form
/
Add
6-5
6-5.
6-6
djangobook.py3k.cn/2.0/chapter06/
5/15
2010-5-5
Admin
6-6. Django
ModelsAdmin
`` book``
Publisher Author Book
`` http://127.0.0.1:8000/admin/`` BooksAuthorsBooks
Publishers (`` runserver`` )
1
Publisher
`` Book``
`` Book``
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
Admin
djangobook.py3k.cn/2.0/chapter06/
6/15
2010-5-5
Admin
Django`` url.py`` URLconf`` admin.autodiscover()``
INSTALLED_APPS admin.py appadmin.py
DjangoURLpatterns
URLconf Djangodjango/contrib/admin
URLpatterns
Django
Authoremail
emailBookmysite/books/models.py
emailblank=True
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(**blank=True** )
Django blank=False
__unicode__()
PythonCREATE TABLE blank=True
Author email
VARCHAR
blank=TrueAdd author edit form
(http://127.0.0.1:8000/admin/books/author/add/ )Email
This field is required
blank=True
SQLNULLNULL
djangobook.py3k.cn/2.0/chapter06/
7/15
2010-5-5
Admin
SQL NULLPythonNone""
VARCHARNULL
NULL
NULL
Django
* *NULL
1
PostgreSQL
MySQL
NULL Djangonull=TrueNULL
DateFieldTimeFieldDateTimeField
IntegerFieldDecimalFieldFloatFieldnull=True * * blank=True
Book publication_date
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField(**blank=True, null=True** )
null=Trueblank=Truenull=TrueCREATE TABLE
publication_dateNOT NULL
DjangoALTER TABLE
manage.py dbshell
NOT NULL:
ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;
2
SQLPostgreSQL
bookpublication date
djangobook.py3k.cn/2.0/chapter06/
8/15
2010-5-5
Admin
Bookpublication_datePublication date
verbose_name
Author.emaile-mail
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, **verbose_name='email'** )
author
verbose_name"USA state"Django
verbose_name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(**'email',**
blank=True)
ManyToManyField ForeignKey
verbose_name
1
ModelAdmi
blank=Truenull=Trueverbose_name
Django ModelAdmin
classes
Author
__unicode__() Author__unicode__()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
1
6-7
6-7.
djangobook.py3k.cn/2.0/chapter06/
9/15
2010-5-5
Admin
AuthorModelAdmin
admin.py
from django.contrib import admin
from mysite.books.models import Publisher, Author, Book
**class AuthorAdmin(admin.ModelAdmin):**
**list_display = ('first_name', 'last_name', 'email')**
admin.site.register(Publisher)
**admin.site.register(Author, AuthorAdmin)**
admin.site.register(Book)
AuthorAdmindjango.contrib.admin.ModelAdmin
list_display
admin.site.register()AuthorAuthorAdmin
AuthorAdminAuthor
admin.site.register() ModelAdmin Django
PublisherBook
author
6-8
6-8. author
AuthorAdminsearch_fields
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')
**search_fields = ('first_name', 'last_name')**
1
6-9.
"bar"BarneyHobarson
6-9. search_fieldsauthor
Book
from django.contrib import admin
from mysite.books.models import Publisher, Author, Book
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')
search_fields = ('first_name', 'last_name')
**class BookAdmin(admin.ModelAdmin):**
**list_display = ('title', 'publisher', 'publication_date')**
djangobook.py3k.cn/2.0/chapter06/
10/15
2010-5-5
Admin
**list_filter = ('publication_date',)**
admin.site.register(Publisher)
admin.site.register(Author, AuthorAdmin)
**admin.site.register(Book, BookAdmin)**
ModelAdminBookAdmin
list_display list_filter
Django
6-10
6-10. book
`` `` `` `` `` `` `` ``
date_hierarchy
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
**date_hierarchy = 'publication_date'**
6-11.
6-11. date_hierarchybook
date_hierarchy* *
publication date class Meta
orderingordering
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
**ordering = ('publication_date',)**
orderingclass Metaordering
(-)
book Publication date 6-12.
6-12 book
djangobook.py3k.cn/2.0/chapter06/
11/15
2010-5-5
Admin
ModelAdminfields
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('publication_date',)
**fields = ('title', 'authors', 'publisher', 'publication_date')**
fieldsfields field(s)
admi
bookpublication_date
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('publication_date',)
**fields = ('title', 'authors', 'publisher')**
publication date
Djangopublication_dateNone
null=True
1
book`` ``
HTML
Ctrlcommand help_text
filter_horizontalBookAdmin
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('publication_date',)
**filter_horizontal = ('authors',)**
fields
bookAuthorJavaScript
authorsAvailableChosen
6-13. filter_horizontalbook
`` `` filter_horizontal
filter_horizontal
ModelAdmin filter_vertical filter_horizontal
djangobook.py3k.cn/2.0/chapter06/
12/15
2010-5-5
Admin
filter_horizontal filter_vertical , ForeignKey
`` `` `` `` `` ``
bookpublishersbook
publishe`` ``
`` raw_id_fields``
`` `` `` `` 6-14
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('publication_date',)
filter_horizontal = ('authors',)
**raw_id_fields = ('publisher',)**
6-14. raw_id_fieldsbook
publisherID ID
publishe
booksauthorspublishers
djangobook.py3k.cn/2.0/chapter06/
13/15
2010-5-5
1
Admin
publishers
Django documentation
Django * * *
* * *
Django
Django
Django
djangobook.py3k.cn/2.0/chapter06/
14/15
2010-5-5
Admin
* *
` <../chapter07/>`__
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter06/
15/15
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
7
GoogleBlogHTML
Django
HttpRequestForm
Request
ViewHttpRequest
viewHttpRequesthello():
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello world")
HttpRequestrequest
viewrequest
URL
HttpRequestURL
/
request.path
"/hello/"
request.get_host()
"127.0.0.1:8000" or
"www.example.com"
request.get_full_path()
request.is_secure()
HTTPSTrue False
"/hello/?print=true"
True False
viewURL
# BAD!
def current_url_view_bad(request):
return HttpResponse("Welcome to the page at /current/")
# GOOD
def current_url_view_good(request):
return HttpResponse("Welcome to the page at %s" % request.path)
request
request.META PythonHTTPHeaderIPAgent
HeaderHeader
Header
1
djangobook.py3k.cn/2.0/chapter07/
1/18
2010-5-5
HTTP_REFERER REFERRER
HTTP_USER_AGENT user-agent
"Mozilla/5.0 (X11; U; Linux i686; frFR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" .
REMOTE_ADDR IP"12.345.67.89" (
IP"12.345.67.89,23.456.78.90" )
request.META Python
KeyError HTTP header
Header
try/except Python get()
# BAD!
def ua_display_bad(request):
ua = request.META['HTTP_USER_AGENT']
view request.META
view
def display_meta(request):
values = request.META.items()
values.sort()
html = []
for k, v in values:
html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v))
return HttpResponse('<table>%s</table>' % '\n'.join(html))
viewDjango
HTML request.path HttpRequest
HttpRequest request.GET
request.POSTGETPOST
request.GETrequest.POSTPython
request.GETrequest.POSTget()keys()values()
for key in request.GET
djangobook.py3k.cn/2.0/chapter07/
2/18
2010-5-5
request.GETrequest.POST
Pythonread()
Python
POSTHTMLformGETformURL
(the query string)
view
HTMLview
view
from django.shortcuts import render_to_response
def search_form(request):
return render_to_response('search_form.html')
viewPython
books/views.py
search_form.html
<html>
<head>
<title>Search</title>
</head>
<body>
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
urls.py URLpattern
from mysite.books import views
urlpatterns = patterns('',
# ...
(r'^searchform/$', views.search_form),
# ...
)
1
djangobook.py3k.cn/2.0/chapter07/
3/18
2010-5-5
URL
3
# urls.py
urlpatterns = patterns('',
# ...
(r'^searchform/$', views.search_form),
(r'^search/$', views.search),
# ...
)
# views.py
def search(request):
if 'q' in request.GET:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.'
return HttpResponse(message)
Django
1. HTMLqqGET(method=get)URL
/search/
2. /search/search()request.GETq
qrequest.GETrequest.META
KeyError
# BAD!
def bad_search(request):
# The following line will raise KeyError if 'q' hasn't
# been submitted!
message = 'You searched for: %r' % request.GET['q']
return HttpResponse(message)
GET/search/?q=django
requet.GET DjangoURLconfDjangoURL
PHP/JavaURLURL
request.GETURLhours=3
POSTGETrequest.POSTrequest.GETPOSTGET
GET
e-mailPOST
GET (GETPOST
http://www.w3.org/2001/tag/doc/whenToUseGet.html)
views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
djangobook.py3k.cn/2.0/chapter07/
4/18
2010-5-5
qrequest.GETreuqest.GET[q]
Book.objects.filter(title__icontains=q)q icontains
Bq
icontains
booksBook search_results.html
pluralizes
djangobook.py3k.cn/2.0/chapter07/
5/18
2010-5-5
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
else:
**return render_to_response('search_form.html', {'error': True})**
search_form()
search()search_form.html
error search_form.htmlerror
<html>
<head>
<title>Search</title>
</head>
<body>
**{% if error %}**
**<p style="color: red;">Please submit a search term.</p>**
**{% endif %}**
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
search_form()search_form()error
search_form
search_form()
/search/GET
search()/search/
search_form()URLpattern
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
return render_to_response('search_form.html',
{'error': error})
/search/GET
URLs/search/
search_form.htmlaction
URL
djangobook.py3k.cn/2.0/chapter07/
6/18
2010-5-5
action=URL search()
action
HTML
email foo e-mail
5U.S 123
YYYY-MM-DD
8
JavaScript
Javascript
JavaScript
JavaScript
search()20
20
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
**elif len(q) > 20:**
**error = True**
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
return render_to_response('search_form.html',
{'error': error})
20
search_form.htmlPlease submit a search term.
djangobook.py3k.cn/2.0/chapter07/
7/18
2010-5-5
<html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
<p style="color: red;">Please submit a search term 20 characters or shorter.</p>
{% endif %}
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
20
def search(request):
**errors = []**
if 'q' in request.GET:
q = request.GET['q']
if not q:
**errors.append('Enter a search term.')**
elif len(q) > 20:
**errors.append('Please enter at most 20 characters.')**
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
return render_to_response('search_form.html',
{**'errors': errors** })
search_form.htmlerrors
<html>
<head>
<title>Search</title>
</head>
<body>
**{% if errors %}**
**<ul>**
**{% for error in errors %}**
**<li>{{ error }}</li>**
**{% endfor %}**
**</ul>**
**{% endif %}**
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
Contact
qDjango
djangobook.py3k.cn/2.0/chapter07/
8/18
2010-5-5
e-mail
e-mail
contact_form.html
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1>
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<form action="/contact/" method="post">
<p>Subject: <input type="text" name="subject"></p>
<p>Your email (optional): <input type="text" name="email"></p>
<p>Message: <textarea name="message" rows="10" cols="50"></textarea></p>
<input type="submit" value="Submit">
</form>
</body>
</html>
e-mail e-mail
method=postmethod=get
e-mail search_form.html
search()contact()
from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def contact(request):
errors = []
if request.method == 'POST':
if not request.POST.get('subject', ''):
errors.append('Enter a subject.')
if not request.POST.get('message', ''):
errors.append('Enter a message.')
if request.POST.get('email') and '@' not in request.POST['email']:
errors.append('Enter a valid email address.')
if not errors:
send_mail(
request.POST['subject'],
request.POST['message'],
request.POST.get('email', 'noreply@example.com'),
['siteowner@example.com'],
)
return HttpResponseRedirect('/contact/thanks/')
return render_to_response('contact_form.html',
{'errors': errors})
djangobook.py3k.cn/2.0/chapter07/
9/18
2010-5-5
contact()books/views.py
contact()books
URLconfURLDjango contact
books__init__.pyviews.py
request.methodPOST
request.methodGET
GETPOSTrequest.method
request.POSTrequest.GET contact_form.html
method=postPOSTrequest.GET
subject message
request.POST.get()
email
@ Django
django.core.mail.send_maile-mail
send_mailDjangoEmailMessageEmailMessage
send_mail()Django
http://docs.djangoproject.com/en/dev/topics/email/
HttpResponseRedirect
/URL/
render_to_response()
POST
POST
POST web
contact()
if
HTML
# views.py
def contact(request):
errors = []
if request.method == 'POST':
if not request.POST.get('subject', ''):
errors.append('Enter a subject.')
djangobook.py3k.cn/2.0/chapter07/
10/18
2010-5-5
# contact_form.html
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1>
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<form action="/contact/" method="post">
<p>Subject: <input type="text" name="subject" **value="{{ subject }}"** ></p>
<p>Your email (optional): <input type="text" name="email" **value="{{ email }}"** ></p>
<p>Message: <textarea name="message" rows="10" cols="50">**{{ message }}**</textarea></p>
<input type="submit" value="Submit">
</form>
</body>
</html>
Form
Djangoformdjango.formsHTML
formcontact
Djangonewforms
1
Djangodjango.newformsdjango.newforms
django.forms
Djangodjango.forms
django.newforms Django
1.0django.formsdjango.newforms
djangobook.py3k.cn/2.0/chapter07/
11/18
2010-5-5
django.forms
HTML`` <Form>`` Form
`` <Form>`` Form `` views.py``
Form forms.py`` views.py``
Form
FieldCharFieldEmailField email
required=False
Python HTML
>>> from contact.forms import ContactForm
>>> f = ContactForm()
>>> print f
<tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" id="id_
<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email"
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_
Django`` <label>``
HTML<`` table`` >
>>> print f.as_ul()
<li><label for="id_subject">Subject:</label> <input type="text" name="subject" id="id_subject" /><
<li><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></li>
<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /><
>>> print f.as_p()
<p><label for="id_subject">Subject:</label> <input type="text" name="subject" id="id_subject" /></
<p><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></p>
<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></
<table><ul><form>
HTML
>>> print f['subject']
<input type="text" name="subject" id="id_subject" />
>>> print f['message']
<input type="text" name="message" id="id_message" />
Form Form
Formform
>>> f.is_bound
djangobook.py3k.cn/2.0/chapter07/
12/18
2010-5-5
True
formis_valid()
Form
>>> f.is_valid()
True
emailrequired=False
>>> f = ContactForm({'subject': 'Hello', 'message': 'Nice site!'})
>>> f.is_valid()
True
subjectmessageForm
>>> f = ContactForm({'subject': 'Hello'})
>>> f.is_valid()
False
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.is_valid()
False
Formerrors
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.errors
{'message': [u'This field is required.']}
Formcleaned_data
DjangoformPython
contact formUnicodeform
Pythondatetime.date
Form
1
Formcontact()
formscontact()
# views.py
djangobook.py3k.cn/2.0/chapter07/
13/18
2010-5-5
DjangoformsHTML
send_mail()
djangobook.py3k.cn/2.0/chapter07/
14/18
2010-5-5
formswidget
Field* * * *
ContactFormsubject100
CharFieldmax_length
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(**max_length=100** )
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
min_length
subject
* * * * * *
unbound
email
Djangoform
form.
djangobook.py3k.cn/2.0/chapter07/
15/18
2010-5-5
Djangoformclean_
clean_message()* *
CharFieldself.cleaned_data
len()split()
forms.ValidationError
1
Python None
HTMLemail
"Email" modelverbose_name
label
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False, **label='Your email address'** )
message = forms.CharField(widget=forms.Textarea)
Form
`` contact_form.html`` `` {{form.as_table}}``
formCSS
`` <ul class=errorlist>``CSS CSS
<style type="text/css">
ul.errorlist {
margin: 0;
padding: 0;
}
.errorlist li {
backgroundcolor: red;
djangobook.py3k.cn/2.0/chapter07/
16/18
2010-5-5
color: white;
display: block;
fontsize: 10px;
margin: 0 0 3px;
padding: 4px 5px;
}
</style>
HTML {{form.as_table}}
formform
(<input type=text>, <select>, <textarea>, ){{form.}}
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
<div class="field">
{{ form.subject.errors }}
<label for="id_subject">Subject:</label>
{{ form.subject }}
</div>
<div class="field">
{{ form.email.errors }}
<label for="id_email">Your email address:</label>
{{ form.email }}
</div>
<div class="field">
{{ form.message.errors }}
<label for="id_message">Message:</label>
{{ form.message }}
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
{{ form.message.errors }} <ul class="errorlist"> form
form.message.errors list
djangobook.py3k.cn/2.0/chapter07/
17/18
2010-5-5
{{ form.message }}
</div>
, divclasserrors
Django
Django
URLconfs
Document License`_.
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter07/
18/18
2010-5-5
URL
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
URL
DjangoURL
URLconf
URLconf Django Python
(Streamlining)
URLconf:
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),
)
URLconf
Django URLconf (
view) views
URLconf
from django.conf.urls.defaults import *
**from mysite import views**
urlpatterns = patterns('',
(r'^hello/$', **views.hello** ),
(r'^time/$', **views.current_datetime** ),
(r'^time/plus/(d{1,2})/$', **views.hours_ahead** ),
)
Django URLconf
:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^hello/$', **'mysite.views.hello'** ),
(r'^time/$', **'mysite.views.current_datetime'** ),
(r'^time/plus/(d{1,2})/$', **'mysite.views.hours_ahead'** ),
)
( 'mysite.views.current_datetime'
djangobook.py3k.cn/2.0/chapter08/
1/17
2010-5-5
URL
mysite.views.current_datetime )
Django
URLconf
``\ \ ``
System Message: WARNING/2 (<string>, line 99); backlink
Inline literal start-string without end-string.
from django.conf.urls.defaults import *
urlpatterns = patterns(**'mysite.views'** ,
(r'^hello/$', **'hello'** ),
(r'^time/$', **'current_datetime'** ),
(r'^time/plus/(d{1,2})/$', **'hours_ahead'** ),
)
("." ) Django
:
Python URLconf
:
(wrap)
Pythonic Python
URLconf
URLconf
patterns() :
:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^hello/$', 'mysite.views.hello'),
(r'^time/$', 'mysite.views.current_datetime'),
(r'^time/plus/(\d{1,2})/$', 'mysite.views.hours_ahead'),
(r'^tag/(\w+)/$', 'weblog.views.tag'),
)
djangobook.py3k.cn/2.0/chapter08/
2/17
2010-5-5
URL
urlpatterns
patterns()
URLconf URL
Django
URL
Python
:
def sell(item, price, quantity):
print "Selling %s unit(s) of %s at %s" % (quantity, item, price)
sell('Socks', '$2.50', 6)
djangobook.py3k.cn/2.0/chapter08/
3/17
2010-5-5
URL
:
sell('Socks', '$2.50', quantity=6)
sell('Socks', price='$2.50', quantity=6)
sell('Socks', quantity=6, price='$2.50')
URLconf :
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', views.year_archive),
(r'^articles/(\d{4})/(\d{2})/$', views.month_archive),
)
URLconf:
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^articles/(?P<year>\d{4})/$', views.year_archive),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', views.month_archive),
)
/articles/2006/03/
month_archive(request, '2006', '03')
URLconfsBUG
URL
month_archive URL
/
djangobook.py3k.cn/2.0/chapter08/
4/17
2010-5-5
URL
URLconfURLconf
DjangoURL
URLconf :
Django
Django
Django
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^foo/$', views.foo_view),
(r'^bar/$', views.bar_view),
)
# views.py
from django.shortcuts import render_to_response
from mysite.models import MyModel
def foo_view(request):
m_list = MyModel.objects.filter(is_new=True)
return render_to_response('template1.html', {'m_list': m_list})
def bar_view(request):
m_list = MyModel.objects.filter(is_new=True)
return render_to_response('template2.html', {'m_list': m_list})
URLURL
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^(foo)/$', views.foobar_view),
(r'^(bar)/$', views.foobar_view),
)
# views.py
from django.shortcuts import render_to_response
from mysite.models import MyModel
djangobook.py3k.cn/2.0/chapter08/
5/17
2010-5-5
URL
URL URLconf
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^foo/$', views.foobar_view, {'template_name': 'template1.html'}),
(r'^bar/$', views.foobar_view, {'template_name': 'template2.html'}),
)
# views.py
from django.shortcuts import render_to_response
from mysite.models import MyModel
def foobar_view(request, template_name):
m_list = MyModel.objects.filter(is_new=True)
return render_to_response(template_name, {'m_list': m_list})
URLconf template_name
URLconf
Django11
URLconf
URLconf
URL
URLconfURL
URL
/mydata/jan/01/
/mydata/jan/02/
/mydata/jan/03/
# ...
/mydata/dec/30/
/mydata/dec/31/
URLconf
urlpatterns = patterns('',
(r'^mydata/(?P<month>\w{3})/(?P<day>\d\d)/$', views.my_view),
djangobook.py3k.cn/2.0/chapter08/
6/17
2010-5-5
URL
my_view
month/dayURL
URL /mydata/birthday/ URL /mydata/jan/06/
URLconf
urlpatterns = patterns('',
(r'^mydata/birthday/$', views.my_view, {'month': 'jan', 'day': '06'}),
(r'^mydata/(?P<month>\w{3})/(?P<day>\d\d)/$', views.my_view),
)
monthday
Python
def say_hello(person_name):
print 'Hello, %s' % person_name
def say_goodbye(person_name):
print 'Goodbye, %s' % person_name
URLconfDjango
Event
BlogEntry
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^events/$', views.event_list),
(r'^blog/entries/$', views.entry_list),
)
# views.py
from django.shortcuts import render_to_response
from mysite.models import Event, BlogEntry
djangobook.py3k.cn/2.0/chapter08/
7/17
2010-5-5
URL
def event_list(request):
obj_list = Event.objects.all()
return render_to_response('mysite/event_list.html', {'event_list': obj_list})
def entry_list(request):
obj_list = BlogEntry.objects.all()
return render_to_response('mysite/blogentry_list.html', {'entry_list': obj_list})
# urls.py
from django.conf.urls.defaults import *
from mysite import models, views
urlpatterns = patterns('',
(r'^events/$', views.object_list, {'model': models.Event}),
(r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}),
)
# views.py
from django.shortcuts import render_to_response
def object_list(request, model):
obj_list = model.objects.all()
template_name = 'mysite/%s_list.html' % model.__name__.lower()
return render_to_response(template_name, {'object_list': obj_list})
object_list
model URLconf
model.objects.all()
model.__name__.lower() Python __name__
BlogEntry
__name__ 'BlogEntry'
blogentry_list event_list
Django
Django
Django
URLconf
djangobook.py3k.cn/2.0/chapter08/
8/17
2010-5-5
URL
URLconf URLconf
URLconfURLconf
URLconf
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^mydata/(?P<id>\d+)/$', views.my_view, {'id': 3}),
)
id id
/mydata/2/ /mydata/432432/ id 3 URL
id
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^blog/$', views.page),
(r'^blog/page(?P<num>\d+)/$', views.page),
)
# views.py
def page(request, num='1'):
# Output the appropriate page of blog entries, according to num.
# ...
URL views.page
page() num "1" page()
num
`` 1`` `` 1`` ``
num``
djangobook.py3k.cn/2.0/chapter08/
9/17
2010-5-5
URL
var = do_something()
return render_to_response(template_name, {'var': var})
URLconfURLURL
URLconf
URLpatternDjango
urlpatterns = patterns('',
# ...
('^([^/]+)/([^/]+)/add/$', views.add_stage),
# ...
)
URL
URLconf
urlpatterns = patterns('',
# ...
('^auth/user/add/$', views.user_add_stage),
('^([^/]+)/([^/]+)/add/$', views.add_stage),
# ...
)
URL
Python
URLConf
(r'^articles/(?P<year>\d{4})/$', views.year_archive),
Python
Python
datetime.date
>>> import datetime
>>> datetime.date('1993', '7', '9')
Traceback (most recent call last):
...
djangobook.py3k.cn/2.0/chapter08/
10/17
2010-5-5
URL
URLconf
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^articles/(\d{4})/(\d{2})/(\d{2})/$', views.day_archive),
)
# views.py
import datetime
def day_archive(request, year, month, day):
# The following statement raises a TypeError!
date = datetime.date(year, month, day)
day_archive()
def day_archive(request, year, month, day):
date = datetime.date(int(year), int(month), int(day))
int() ValueError
URLconf
URLconf
DjangoURLPythonURLconf
Unicode GET POST URL
URLconf/view :
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
# ...
(r'^somepage/$', views.some_page),
# ...
)
# views.py
djangobook.py3k.cn/2.0/chapter08/
11/17
2010-5-5
URL
`` some_page()``
# views.py
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
def method_splitter(request, GET=None, POST=None):
if request.method == 'GET' and GET is not None:
return GET(request)
elif request.method == 'POST' and POST is not None:
return POST(request)
raise Http404
def some_page_get(request):
assert request.method == 'GET'
do_something_for_get()
return render_to_response('page.html')
def some_page_post(request):
assert request.method == 'POST'
do_something_for_post()
return HttpResponseRedirect('/someurl/')
# urls.py
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
# ...
(r'^somepage/$', views.method_splitter, {'GET': views.some_page_get, 'POST': views.some_page_p
# ...
)
`` method_splitter()`` `` request.method``
`` GET`` `` POST`` * * ``
request.method`` `` GET`` `` GET`` `` request.method``
djangobook.py3k.cn/2.0/chapter08/
12/17
2010-5-5
URL
`` POST`` `` POST`` `` request.method`` ``
HEAD`` `` GET`` `` POST`` `` Http404``
,method_splitter(),GETPOST,*args**kwargs(*
) Python
,*,. ,
*,,
>>> foo(1, 2, 3)
Positional arguments are:
(1, 2, 3)
Keyword arguments are:
{}
>>> foo(1, 2, name='Adrian', framework='Django')
Positional arguments are:
(1, 2)
djangobook.py3k.cn/2.0/chapter08/
13/17
2010-5-5
URL
method_splitter()*args**kwargs
any kwargs.pop()GETPOST (
popNone,KeyError)
python
def my_view1(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
# ...
return render_to_response('template1.html')
def my_view2(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
# ...
return render_to_response('template2.html')
def my_view3(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
# ...
return render_to_response('template3.html')
request.user
/accounts/login/ (,request.user,14.
,request.user)
1
def requires_login(view):
def new_view(request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
return view(request, *args, **kwargs)
return new_view
requires_login,view,new_view.new_view
requires_login request.user.is_authenticated(),view
djangobook.py3k.cn/2.0/chapter08/
14/17
2010-5-5
URL
, ,requires_login()
URLconf
DjangoURLconf
URLconfURLconf URL
URLconfURLConf
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^weblog/', include('mysite.blog.urls')),
(r'^photos/', include('mysite.photos.urls')),
(r'^about/$', 'mysite.views.about'),
)
6Djangoadmininclude. adminURLconf,
include.
include() $
Django include() URL
URLconf
URLconf mysite.blog.urls
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail'),
(r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail'),
)
URLconf
/weblog/2007/ URLconf r'^weblog/' include() Django
/weblog//2007/() URLconf,r^weblog/
include(),django,weblog/ /2007/ (
),mysite.blog.urls.
/about/ : URLconf mysite.views.about
include()
URLconfparent URLconfs:
# root urls.py
djangobook.py3k.cn/2.0/chapter08/
15/17
2010-5-5
URL
username URLconfURLconf
URLconf
URLconfinclude()
URLconf include() , URLconf
URLconf
1
URLconf
# urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^blog/', include('inner'), {'blogid': 3}),
)
# inner.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
(r'^rss/$', 'mysite.views.rss'),
)
# urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^blog/', include('inner')),
)
# inner.py
djangobook.py3k.cn/2.0/chapter08/
16/17
2010-5-5
URL
URLconf
URLconf
URLconfs Chapter 9,
djangos
GNU Free Document License. Hosting
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter08/
17/17
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Django
Django
django
DjangoDjango
Django
DjangoPython
iffor ),
{% %}
{% if is_logged_in %}
Thanks for logging in!
{% else %}
Please log in.
{% endif %}
{{ }}
My first name is {{ first_name }}. My last name is {{ last_name }}.
context Python
context
RequestContextContext
context django.template.Context Django
django.template.RequestContext RequestContext
context HttpRequest
djangobook.py3k.cn/2.0/chapter09/
1/19
2010-5-5
RequestContext
render_to_response()
context
appuserip_address
RequestContext context Context
context render_to_response()
RequestContext Context
context RequestContext context
processors
from django.template import loader, RequestContext
def custom_proc(request):
"A context processor that provides 'app', 'user' and 'ip_address'."
return {
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR']
}
def view_1(request):
# ...
t = loader.get_template('template1.html')
c = RequestContext(request, {'message': 'I am view 1.'},
processors=[custom_proc])
return t.render(c)
def view_2(request):
# ...
t = loader.get_template('template2.html')
c = RequestContext(request, {'message': 'I am the second view.'},
djangobook.py3k.cn/2.0/chapter09/
2/19
2010-5-5
processors=[custom_proc])
return t.render(c)
message
render_to_response() loader.get_template() ,
Context render() context
render_to_response() render_to_response() context
context_instance
from django.shortcuts import render_to_response
from django.template import RequestContext
def custom_proc(request):
"A context processor that provides 'app', 'user' and 'ip_address'."
return {
'app': 'My app',
'user': request.user,
'ip_address': request.META['REMOTE_ADDR']
}
def view_1(request):
# ...
return render_to_response('template1.html',
{'message': 'I am view 1.'},
context_instance=RequestContext(request, processors=[custom_proc]))
def view_2(request):
# ...
return render_to_response('template2.html',
{'message': 'I am the second view.'},
context_instance=RequestContext(request, processors=[custom_proc]))
processors
processors context
Django context TEMPLATE_CONTEXT_PROCESSORS
djangobook.py3k.cn/2.0/chapter09/
3/19
2010-5-5
custom_proc
requestcontext request
context
context
Djangocontext
django.core.context_processors.auth
TEMPLATE_CONTEXT_PROCESSORS RequestContext
user django.contrib.auth.models.User AnonymousUser
messages
request.user.get_and_delete_messages()
perms django.core.context_processors.PermWrapper
userspermissionsmessages14
django.core.context_processors.debug
TEMPLATE_CONTEXT_PROCESSORS
RequestContext
debug DEBUG True False debug
SQL
System Message: WARNING/2 (<string>, line 315); backlink
Inline literal start-string without end-string.
context
DEBUG True
djangobook.py3k.cn/2.0/chapter09/
4/19
2010-5-5
ip INTERNAL_IPS
debugFalseDEBUGFalsedebug
RequestContext
django.core.context_processors.i18n
RequestContext
LANGUAGES LANGUAGES
django.core.context_processors.request
RequestContext request HttpRequest
HttpRequest:
{{ request.REMOTE_ADDR }}
Context
context
Python
TEMPLATE_CONTEXT_PROCESSORS
context_processors.py
html
htmlhtml
<script>alert('hello')</script>
djangobook.py3k.cn/2.0/chapter09/
5/19
2010-5-5
Hello, <script>alert('hello')</script>
JavaScript
Hello, <b>username
(XSS) 20
escapehtml
Django
Djangohtml
django
1
``\ ``
System Message: WARNING/2 (<string>, line 491); backlink
Inline literal start-string without end-string.
> >
' '
" ()"
django
html
html
Djangohtmle-mail
djangobook.py3k.cn/2.0/chapter09/
6/19
2010-5-5
safe
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
,autoescape(),
{% autoescape off %}
Hello {{ name }}
{% endautoescape %}
autoescape onoff ,,
auto-escaping include,block
# base.html
{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}
# child.html
{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}
1
base,child.,HTML,
greetingHello!
<h1>This & that</h1>
<b>Hello!</b>
djangobook.py3k.cn/2.0/chapter09/
7/19
2010-5-5
,. Pyhton(VIEWS)
,,
,escape
escapeescape
,.
{{ data|default:"This is a string literal." }}
,safe
,
,,
template loaders
Django
django.template.loader.get_template(template_name) get_template
Template TemplateDoesNotExist
django.template.loader.select_template(template_name_list) select_template
get_template
TemplateDoesNotExist
TEMPLATE_DIRS
TEMPLATE_LOADERS TEMPLATE_LOADERS
Django
django.template.loaders.filesystem.load_template_source : TEMPLATE_DIRS
django.template.loaders.app_directories.load_template_source : Django
INSTALLED_APPS templates
djangobook.py3k.cn/2.0/chapter09/
8/19
2010-5-5
Django
Django
INSTALLED_APPS ('myproject.polls','myproject.music') get_template('foo.html')
/path/to/myproject/polls/templates/foo.html
/path/to/myproject/music/templates/foo.html
INSTALLED_APPS
templates
django.template.loaders.eggs.load_template_source : app_directories
/ Django
Django
INSTALLED_APPS
Django templatetags models.py views.py
books/
__init__.py
models.py
templatetags/
views.py
djangobook.py3k.cn/2.0/chapter09/
9/19
2010-5-5
/ poll_extras.py
{% load poll_extras %}
{% load %} INSTALLED_APPS Django
Django
/ templatetags Django
templatetags
{%load%}Python/
PythonPython
registertemplate.Library
from django import template
register = template.Library()
Django
django/template/defaultfilters.py django/template/defaulttags.py django.contrib
register
Python:
()
{{ var|foo:"bar" }} foo var bar
{{ somevariable|cut:" " }}
def lower(value): # Only one argument.
djangobook.py3k.cn/2.0/chapter09/
10/19
2010-5-5
Library Django
register.filter('cut', cut)
register.filter('lower', lower)
Library.filter()
Python 2.4register.filter()
@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg, '')
@register.filter
def lower(value):
return value.lower()
name Django
cut
from django import template
register = template.Library()
@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg, '')
Django
Django django.template.Node
render()
Hello, {{ person.name }}.
{% ifequal name.birthday today %}
Happy birthday!
{% else %}
Be sure to come back on your birthday
for a splendid surprise message.
{% endifequal %}
"Hello, "
djangobook.py3k.cn/2.0/chapter09/
11/19
2010-5-5
person.name
: ".\n\n"
IfEqual: name.birthdaytoday
render() context
render()
render()
template tag
python Node
{% current_time %} strftime
http://www.djangoproject.com/r/python/strftime/
, Django {% now %}
Node :
from django import template
register = template.Library()
def do_current_time(parser, token):
try:
# split_contents() knows not to split quoted strings.
tag_name, format_string = token.split_contents()
except ValueError:
msg = '%r tag requires a single argument' % token.split_contents()[0]
raise template.TemplateSyntaxError(msg)
return CurrentTimeNode(format_string[1:1])
parsertokenparser
token
token.contents
'current_time "%Y%m%d %I:%M %p"'
token.split_contents()
djangobook.py3k.cn/2.0/chapter09/
12/19
2010-5-5
token.contents.split() Python
django.template.TemplateSyntaxError
token.split_contents()[0]
CurrentTimeNode
"%Y%m%d %I:%M %p"
format_string[1:1]
Node
render() Node
CurrentTimeNode
import datetime
class CurrentTimeNode(template.Node):
def __init__(self, format_string):
self.format_string = str(format_string)
def render(self, context):
now = datetime.datetime.now()
return now.strftime(self.format_string)
__init__() render()
render()
Library
template.Library tag()
register.tag('current_time', do_current_time)
tag() :
Python2.4 register.tag
@register.tag(name="current_time")
def do_current_time(parser, token):
djangobook.py3k.cn/2.0/chapter09/
13/19
2010-5-5
# ...
@register.tag
def shout(parser, token):
# ...
name Django
render() context
CurrentTimeNode current_time
class CurrentTimeNode2(template.Node):
def __init__(self, format_string):
self.format_string = str(format_string)
def render(self, context):
now = datetime.datetime.now()
context['current_time'] = now.strftime(self.format_string)
return ''
(do_current_time2current_time2)
render() render()
render()
CurrentTimeNode2 : current_time
{{ current_time }} {% current_time2 %}
Node
import re
class CurrentTimeNode3(template.Node):
def __init__(self, format_string, var_name):
self.format_string = str(format_string)
self.var_name = var_name
def render(self, context):
now = datetime.datetime.now()
context[self.var_name] = now.strftime(self.format_string)
return ''
def do_current_time(parser, token):
# This version uses a regular expression to parse tag contents.
djangobook.py3k.cn/2.0/chapter09/
14/19
2010-5-5
try:
# Splitting by None == splitting by spaces.
tag_name, arg = token.contents.split(None, 1)
except ValueError:
msg = '%r tag requires arguments' % token.contents[0]
raise template.TemplateSyntaxError(msg)
m = re.search(r'(.*?) as (\w+)', arg)
if m:
fmt, var_name = m.groups()
else:
msg = '%r tag had invalid arguments' % tag_name
raise template.TemplateSyntaxError(msg)
if not (fmt[0] == fmt[1] and fmt[0] in ('"', "'")):
msg = "%r tag's argument should be in quotes" % tag_name
raise template.TemplateSyntaxError(msg)
return CurrentTimeNode3(fmt[1:1], var_name)
do_current_time() CurrentTimeNode3
{% if %} {% for %}
parser.parse()
{% comment %}
def do_comment(parser, token):
nodelist = parser.parse(('endcomment',))
parser.delete_first_token()
return CommentNode()
class CommentNode(template.Node):
def render(self, context):
return ''
parser.parse()
django.template.NodeListNode
.
nodelist {% comment %} {% endcomment %}
{% comment %} {% endcomment %}
parser.parse() {% endcomment %}
parser.delete_first_token()
djangobook.py3k.cn/2.0/chapter09/
15/19
2010-5-5
{% upper %}
This will appear in uppercase, {{ user_name }}.
{% endupper %}
UpperNode.render() self.nodelist.render(context)
Node render()
current_time
Djangosimple_tagdjango.template.Library
render
current_time
def current_time(format_string):
try:
return datetime.datetime.now().strftime(str(format_string))
except UnicodeEncodeError:
return ''
register.simple_tag(current_time)
Python 2.4
@register.simple_tag
def current_time(token):
# ...
simple_tag
djangobook.py3k.cn/2.0/chapter09/
16/19
2010-5-5
Unicode
Django
/
{% books_for_author author %}
<ul>
<li>The Cat In The Hat</li>
<li>Hop On Pop</li>
<li>Green Eggs And Ham</li>
</ul>
def books_for_author(author):
books = Book.objects.filter(authors__id=author.id)
return {'books': books}
<ul>
{% for book in books %}
<li>{{ book.title }}</li>
{% endfor %}
</ul>
Library inclusion_tag()
polls/result_snippet.html
register.inclusion_tag('book_snippet.html')(books_for_author)
Python 2.4
@register.inclusion_tag('book_snippet.html')
def books_for_author(author):
# ...
context Django
takes_context
Python context
home_link home_title Python
@register.inclusion_tag('link.html', takes_context=True)
def jump_link(context):
djangobook.py3k.cn/2.0/chapter09/
17/19
2010-5-5
return {
'link': context['home_link'],
'title': context['home_title'],
}
context
link.html
Jump directly to <a href="{{ link }}">{{ title }}</a>.
{% jump_link %}
Djangos
PythonSubversionZIP
TEMPLATE_LOADERS
load_template_source(template_name, template_dirs=None)
django.template.TemplateDoesNotExist
is_usable
Python pkg_resources eggs
python eggs is_usable False pkg_resources eggs
ZIP
TEMPLATE_ZIP_FILES TEMPLATE_DIRS
ZIP
from django.conf import settings
from django.template import TemplateDoesNotExist
import zipfile
def load_template_source(template_name, template_dirs=None):
"Template loader that loads templates from a ZIP file."
template_zipfiles = getattr(settings, "TEMPLATE_ZIP_FILES", [])
# Try each ZIP file in TEMPLATE_ZIP_FILES.
for fname in template_zipfiles:
try:
z = zipfile.ZipFile(fname)
source = z.read(template_name)
djangobook.py3k.cn/2.0/chapter09/
18/19
2010-5-5
TEMPLATE_LOADERS
mysite.zip_loadermysite.zip_loader.load_template_source
TEMPLATE_LOADERS
Django
Django DJANGO_SETTINGS_MODULE
PythonDjango
D
Django.conf.settings.configure()
TEMPLATE_DIRS DEFAULT_CHARSET
utf8 TEMPLATE_DEBUG D TEMPLATE_
Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter09/
19/19
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
10
5DjangoAPI
Django
(book)
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
5, ,ID50,
:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
,ForeignKey ManyToManyField,
(Foreign Key)
ForeignKey , :
djangobook.py3k.cn/2.0/chapter10/
1/9
2010-5-5
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
`` ForeignKey``
`` publisher`` books publisher.book_set.all()
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
book_set QuerySet5QuerySet,
book_set(book)_set
(Many-to-Many Values)
QuerySet ,
>>> b = Book.objects.get(id=50)
>>> b.authors.all()
[<Author: Adrian Holovaty>, <Author: Jacob KaplanMoss>]
>>> b.authors.filter(first_name='Adrian')
[<Author: Adrian Holovaty>]
>>> b.authors.filter(first_name='Adam')
[]
,author.book_set ,:
>>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty')
>>> a.book_set.all()
[<Book: The Django Book>, <Book: Adrian's Other Book>]
, ForeignKeybook_set(model)_set
(Database Schema)
5 syncdb , syncdb
, ,
Django
Django Django
API
Django
djangobook.py3k.cn/2.0/chapter10/
2/9
2010-5-5
Django
Python
(model)Django
model Django
,SQLDjango
manage.py sqlall , (:
Django
SQL ,)
- (/
?)
()
1.
2. manage.py sqlall [yourapp] CREATE TABLE
3. (, psql mysql , manage.py dbshell )
ALTER TABLE
4. Pythonmanage.py shell ( MyModel.objects.all()[:5] )
,,
1.
2. ALTER TABLE
3.
Subversionsvn update
4. Web server
num_pagesBook
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
**num_pages = models.IntegerField(blank=True, null=True)**
def __unicode__(self):
return self.title
(
blank=Truenull=True)
djangobook.py3k.cn/2.0/chapter10/
3/9
2010-5-5
PostgreSQL psql,
ALTER TABLE books_book ADD COLUMN num_pages integer;
NULL
num_pages blank=True null=True
NULL
NOT NULL
BEGIN;
ALTER TABLE books_book ADD COLUMN num_pages integer;
UPDATE books_book SET num_pages=0;
ALTER TABLE books_book ALTER COLUMN num_pages SET NOT NULL;
COMMIT;
blank=True null=True
ALTER TABLEpython
>>> from mysite.books.models import Book
>>> Book.objects.all()[:5]
ALTER TABLE
web
Model
web
Django
djangobook.py3k.cn/2.0/chapter10/
4/9
2010-5-5
ManyToManyFieldweb
web models.py
books_book
Managers
Book.objects.all()objects 5
manager managers
managerDjango Django
managermanager
manager manager/manager
QuerySet
Manager
manager
,Booktitle_count()
managers
# models.py
from django.db import models
# ... Author and Publisher models here ...
**class BookManager(models.Manager):**
**def title_count(self, keyword):**
**return self.filter(title__icontains=keyword).count()**
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
num_pages = models.IntegerField(blank=True, null=True)
djangobook.py3k.cn/2.0/chapter10/
5/9
2010-5-5
**objects = BookManager()**
def __unicode__(self):
return self.title
manager
>>> Book.objects.title_count('django')
4
>>> Book.objects.title_count('python')
18
BookManagerdjango.db.models.Manager
title_count() self.filter()selfmanager
BookManager()objects managerobjects
objectsmanager
title_count()?
Manager QuerySets
managerQuerySet ,`` Book.objects.all()`` book
Manager.get_query_set()managerQuerySet get_query_set()
QuerySet
,* * managerRoald Dahl
from django.db import models
**# First, define the Manager subclass.**
**class DahlBookManager(models.Manager):**
**def get_query_set(self):**
**return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')**
**# Then hook it into the Book model explicitly.**
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
# ...
**objects = models.Manager() # The default manager.**
**dahl_objects = DahlBookManager() # The Dahlspecific manager.**
,Book.objects.all(),Book.dahl_objects.all().
objectsmanagermanager
dah1_objects
,get_query_set()QuerySetfilter()exclude()
QuerySet
djangobook.py3k.cn/2.0/chapter10/
6/9
2010-5-5
Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()
manager
manager()
:
class MaleManager(models.Manager):
def get_query_set(self):
return super(MaleManager, self).get_query_set().filter(sex='M')
class FemaleManager(models.Manager):
def get_query_set(self):
return super(FemaleManager, self).get_query_set().filter(sex='F')
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
people = models.Manager()
men = MaleManager()
women = FemaleManager()
ManagerDjangoManager()
DjangoManager Manager Django(
admin)manager manager
get_query_set()
manager
table-wide
from django.contrib.localflavor.us.models import USStateField
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()
address = models.CharField(max_length=100)
city = models.CharField(max_length=50)
state = USStateField() # Yes, this is U.S.centric...
def baby_boomer_status(self):
"Returns the person's babyboomer status."
import datetime
if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
return "Baby boomer"
if self.birth_date < datetime.date(1945, 8, 1):
djangobook.py3k.cn/2.0/chapter10/
7/9
2010-5-5
return "Preboomer"
return "Postboomer"
def is_midwestern(self):
"Returns True if this person is from the Midwest."
return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')
def _get_full_name(self):
"Returns the person's full name."
return u'%s %s' % (self.first_name, self.last_name)
full_name = property(_get_full_name)
property
http://www.python.org/download/releases/2.2/descrintro/#property
u'Barack Obama'
SQL
DjangoAPISQL
django.db.connection
connection.cursor() cursor.execute(sql, [params])SQL
cursor.fetchone()cursor.fetchall() :
>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute("""
...
...
FROM people_person
...
WHERE last_name = %s""", ['Lennon'])
>>> row = cursor.fetchone()
>>> print row
['John']
connection cursor Python DB-API` http://www.python.org/peps/pep-
django.db.connectionmanager
manager
from django.db import connection, models
class PersonManager(models.Manager):
def first_names(self, last_name):
cursor = connection.cursor()
cursor.execute("""
SELECT DISTINCT first_name
djangobook.py3k.cn/2.0/chapter10/
8/9
2010-5-5
FROM people_person
WHERE last_name = %s""", [last_name])
return [row[0] for row in cursor.fetchone()]
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
objects = PersonManager()
:
>>> Person.objects.first_names('Lennon')
['John', 'Cynthia']
Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter10/
9/9
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
11
Web
Django Web
Django
URLConf
Django
8 event_list entry_list
event
// Django Weblogs
(http://www.djangoproject.com/weblog/)
URLconfURLconf
URLconf
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'
})
)
direct_to_template
about
URL /about// about/.html URL
djangobook.py3k.cn/2.0/chapter11/
1/8
2010-5-5
about_pages
from django.http import Http404
from django.template import TemplateDoesNotExist
from django.views.generic.simple import direct_to_template
def about_pages(request, page):
try:
return direct_to_template(request, template="about/%s.html" % page)
except TemplateDoesNotExist:
raise Http404()
1
direct_to_template HttpResponse
TemplateDoesNotExist404
(template="about/%s.html" % page ) directory traversal
20
page page URL
URL \w+ URL page \w
. / URL
direct_to_template Django
Django
Publisher
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Meta:
djangobook.py3k.cn/2.0/chapter11/
2/8
2010-5-5
ordering = ['name']
URL
from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher
publisher_info = {
'queryset': Publisher.objects.all(),
}
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info)
)
Python
template_nameobject_list
from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher
publisher_info = {
'queryset': Publisher.objects.all(),
**'template_name': 'publisher_list_page.html',**
}
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info)
)
template_nameobject_list
"books/publisher_list.html" booksapp publisher
context object_list
{% extends "base.html" %}
{% block content %}
<h2>Publishers</h2>
<ul>
{% for publisher in object_list %}
<li>{{ publisher.name }}</li>
{% endfor %}
</ul>
{% endblock %}
(base.html
D
Django
djangobook.py3k.cn/2.0/chapter11/
3/8
2010-5-5
Context
object_list
publisher_list
template_object_name
from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher
publisher_info = {
'queryset': Publisher.objects.all(),
'template_name': 'publisher_list_page.html',
'template_object_name': 'publisher',
}
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info)
)
1
template_object_name_list
template_object_name
Context
object_detail context
extra_context
context info
publisher_info = {
'queryset': Publisher.objects.all(),
'template_object_name': 'publisher',
**'extra_context': {'book_list': Book.objects.all()}**
}
{{ book_list }} context
BUG
2
extra_context
Publisher.objects.all() URLconfURLconf
WebQuerySet
C
djangobook.py3k.cn/2.0/chapter11/
4/8
2010-5-5
extra_context callback
extra_context
**def get_books():**
**return Book.objects.all()**
publisher_info = {
'queryset': Publisher.objects.all(),
'template_object_name': 'publisher',
'extra_context': **{'book_list': get_books}**
}
Publisher.objects.all
publisher_info = {
'queryset': Publisher.objects.all(),
'template_object_name': 'publisher',
'extra_context': **{'book_list': Book.objects.all}**
}
Book.objects.all
queryset queryset
QuerySet B
book_info = {
'queryset': Book.objects.order_by('publication_date'),
}
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info),
**(r'^books/$', list_detail.object_list, book_info),**
)
**apress_books = {**
**'queryset': Book.objects.filter(publisher__name='Apress Publishing'),**
**'template_name': 'books/apress_list.html'**
**}**
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info),
**(r'^books/apress/$', list_detail.object_list, apress_books),**
)
djangobook.py3k.cn/2.0/chapter11/
5/8
2010-5-5
queryset
URLURL
URL URLconf
object_list URL
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info),
**(r'^books/(\w+)/$', books_by_publisher),**
)
books_by_publisher
from django.shortcuts import get_object_or_404
from django.views.generic import list_detail
from mysite.books.models import Book, Publisher
def books_by_publisher(request, name):
# Look up the publisher (and raise a 404 if it can't be found).
publisher = get_object_or_404(Publisher, name__iexact=name)
# Use the object_list view for the heavy lifting.
return list_detail.object_list(
request,
queryset = Book.objects.filter(publisher=publisher),
template_name = 'books/books_by_publisher.html',
template_object_name = 'book',
extra_context = {'publisher': publisher}
)
Python
HttpResponse
extra_context
URL
from mysite.books.views import author_detail
djangobook.py3k.cn/2.0/chapter11/
6/8
2010-5-5
urlpatterns = patterns('',
# ...
**(r'^authors/(?P<author_id>\d+)/$', author_detail),**
# ...
)
import datetime
from django.shortcuts import get_object_or_404
from django.views.generic import list_detail
from mysite.books.models import Author
def author_detail(request, author_id):
# Delegate to the generic view and get an HttpResponse.
response = list_detail.object_detail(
request,
queryset = Author.objects.all(),
object_id = author_id,
)
# Record the last accessed date. We do this *after* the call
# to object_detail(), not before it, so that this won't be called
# unless the Author actually exists. (If the author doesn't exist,
# object_detail() will raise Http404, and we won't reach this point.)
now = datetime.datetime.now()
Author.objects.filter(id=author_id).update(last_accessed=now)
return response
author
def author_list_plaintext(request):
response = list_detail.object_list(
request,
queryset = Author.objects.all(),
mimetype = 'text/plain',
template_name = 'books/author_list.txt'
)
response["ContentDisposition"] = "attachment; filename=authors.txt"
return response
HttpResponse HTTP
ContentDisposition
Django C
, Django
djangobook.py3k.cn/2.0/chapter11/
7/8
2010-5-5
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter11/
8/8
2010-5-5
Django
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Django
django
runserver runserver django
Apache ()
.
runserver **
Debug.
2, djangoadmin.py startproject , settings.py DEBUG
True . django DEBUG . DEBUG
True , :
django.db.connection.queries .
!
404django404(3)404
python
Django 404
`` DEBUG`` `` True`` Django Internet
`` DEBUG`` `` False``
Debug
TEMPLATE_DEBUGFalse `` True``
Django
1
404
`` DEBUG`` `` True`` Django404 `` DEBUG`` ``
False`` `` 404.html``
`` 404.html`` `` base.html``,
titlecontent
{% extends "base.html" %}
djangobook.py3k.cn/2.0/chapter12/
1/18
2010-5-5
Django
500
`` DEBUG`` `` False`` DjangPython
`` 500.html`` `` 404.html``
500.html`` ``
`` 500.html``
<!DOCTYPE html PUBLIC "//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Page unavailable</title>
</head>
<body>
<h1>Page unavailable</h1>
<p>Sorry, but the requested page is unavailable due to a
server hiccup.</p>
<p>Our engineers have been notified, so check back later.</p>
</body>
</html>
Django Django
Email
ADMINSE-mailE-mail
(, Email)
ADMINS = (
('John Lennon', 'jlennon@example.com'),
('Paul McCartney', 'pmacca@example.com'),
)
postfix,sendmailDjango
, EMAIL_HOST.
localhost, . ,
EMAIL_HOST_USER,EMAIL_HOST_PASSWORD,EMAIL_PORTEMAIL_USE_TLS
djangobook.py3k.cn/2.0/chapter12/
2/18
2010-5-5
Django
CommonMiddleware(MIDDLEWARE_CLASSES
django.middleware.common.CommonMiddleware
CommonMiddleware),Django
404.
SEND_BROKEN_LINK_EMAILS True(False),MANAGERS
. MANAGERSADMINS .:
MANAGERS = (
('George Harrison', 'gharrison@example.com'),
('Ringo Starr', 'ringo@example.com'),
)
settings.pydjango-admin.py startproject
DEBUGFalse TrueDjango
))
.
Python
settings.pysettings_production.py
),DEBUG
# settings.py
DEBUG = True
TEMPLATE_DEBUG = DEBUG
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_NAME = 'devdb'
DATABASE_USER = ''
djangobook.py3k.cn/2.0/chapter12/
3/18
2010-5-5
Django
DATABASE_PASSWORD = ''
DATABASE_PORT = ''
# ...
# settings_production.py
from settings import *
DEBUG = TEMPLATE_DEBUG = False
DATABASE_NAME = 'production'
DATABASE_USER = 'app'
DATABASE_PASSWORD = 'letmein'
settings_production.py settings.py
DEBUG False
DEBUG
# settings.py
import socket
if socket.gethostname() == 'mylaptop':
DEBUG = TEMPLATE_DEBUG = True
else:
DEBUG = TEMPLATE_DEBUG = False
# ...
pythonsocket
pythonpython
) Django
settings.py
settings.pysettings_dev.pysettings/dev.pyfoobar.pyDjango
DJANGO_SETTINGS_MODULE
(Apache)
Web
DJANGO_SETTINGS_MODULE,Django DJANGO_SETTINGS_MODULE
ROOT_URLCONF,ROOT_URLCONF
djangobook.py3k.cn/2.0/chapter12/
4/18
2010-5-5
Django
DJANGO_SETTINGS_MODULEpython mysitePython
DJANGO_SETTINGS_MODULEmysite.settings
Apachemod_pythonDjango
Apachemod_pythonDjango
mod_python (http://www.djangoproject.com/r/mod_python/)ApachePythonApache
Python (
Django Apaceh 2.x mod_python 3.x
Apache
Apache :
Apache http://www.djangoproject.com/r/apache/docs/
Then, edit your Apache configuration file and add a <Location> directive that ties a specific URL path
to a specific Django installation.
<Location "/">
SetHandler pythonprogram
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug Off
</Location>
DJANGO_SETTINGS_MODULE mysite.settings
Apache / URL Django mod_python
DJANGO_SETTINGS_MODULE mod_python
djangobook.py3k.cn/2.0/chapter12/
5/18
2010-5-5
Django
Apache Django
Apache Django Web
VirtualHost
NameVirtualHost *
<VirtualHost *>
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</VirtualHost>
djangobook.py3k.cn/2.0/chapter12/
6/18
2010-5-5
Django
<VirtualHost *>
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
</VirtualHost>
<VirtualHost *>
ServerName www.example.com
# ...
<Location "/something">
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonInterpreter mysite
</Location>
<Location "/otherthing">
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
PythonInterpreter mysite_other
</Location>
</VirtualHost>
PythonInterpreter Location
mod_python
mod_python Python mod_python Django
Apache
MaxRequestsPerChild 1 Apache
Django
print print mod_python
Apache mod_python
Python Pythons standard logging package
http://docs.python.org/lib/module-logging.html
ApacheDjangoMedia
Djangomedia
Djangomedia
DjangoApache VirtualHost media
mod_python
<Location "/media/">
SetHandler None
</Location>
Location media
<LocationMatch> Django
media .jpg .gif .png URL:
<Location "/">
SetHandler pythonprogram
PythonHandler django.core.handlers.modpython
djangobook.py3k.cn/2.0/chapter12/
7/18
2010-5-5
Django
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>
<Location "/media/">
SetHandler None
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler None
</LocationMatch>
DocumentRoot apache
ApacheDjango Django
pyexpat XMLApache
http://www.djangoproject.com/r/articles/expat-apache-crash/.
Apachemod_python mod_phpMySQL
PHPPythonMySQL mod_pythonFAQ
mod_pythonmod_pythonDjango
mod_python
http://www.djangoproject.com/r/articles/getting-modpython-working/.
djangoimport
views,models,URLconf,RSS importshandler
URL crashimportdjango imports
imports
linuxldconfigMac OSotoolwindowsListDLLsform sysInternals
mod_wsgi
mod_pythonmod_wsgi(http://code.google.com/p/modwsgi/),
mod_pythonDjango
Django
FastCGIDjango
djangobook.py3k.cn/2.0/chapter12/
8/18
2010-5-5
Django
Apachemod_pythonDjango
FastCGI
FastCGImod_python
ApacheFastCGI
FastCGI
WEB FastCGI!
mod_pythonFastCGI,CGI
mod_pythonweb
mod_*Apache PHP
Python/mod_pythonPerl/mod_perlapacheApache
ApacheApacheApache
Django FastCGIPythonDjango
FastCGIFastCGIWeb
FastCGI
FastCGI/FastCGI Web
Apache,lighttpdDjango-FastCGI
Fast-CGI
djangobook.py3k.cn/2.0/chapter12/
9/18
2010-5-5
Django
TCP
./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
Unix socketprefork
./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
FastCGI
FastCGICtrl+C
Unix kill Unix
kill
UnixFastCGI
#!/bin/bash
# Replace these three settings.
PROJDIR="/home/user/myproject"
PIDFILE="$PROJDIR/mysite.pid"
SOCKET="$PROJDIR/mysite.sock"
cd $PROJDIR
if [ f $PIDFILE ]; then
kill `cat $PIDFILE`
rm f $PIDFILE
fi
exec /usr/bin/env
PYTHONPATH="../python:.."
ApacheFastCGIDjango
ApacheFastCGIDjangoApachemod_fastcgi Apache
mod_fastcgi http://www.djangoproject.com/r/mod_fastcgi/
httpd.conf ApacheApacheDjango FastCGI
djangobook.py3k.cn/2.0/chapter12/
10/18
2010-5-5
Django
FastCGIExternalServer FastCGI
mod_rewrite FastCGIURL
FastCGI Server
FastCGIExternalServer ApacheFastCGI FastCGIExternalServer
/home/user/public_html/ /home/user/public_html/mysite.fcgi
WebURLURLFastCGI
mod_rewriteFastCGIURL
ApacheURLFastCGI mod_rewrite
URL mysite.fcgi FastCGIExternalServer
ApacheFastCGI(
<VirtualHost 12.34.56.78>
ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !f
RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
</VirtualHost>
FastCGI lighttpd
lighttpd (http://www.djangoproject.com/r/lighttpd/) Web
FastCGIApachelighttpd
lighttpd
server.documentroot = "/home/user/public_html"
fastcgi.server = (
"/mysite.fcgi" => (
"main" => (
# Use host / port instead of socket for TCP fastcgi
# "host" => "127.0.0.1",
# "port" => 3033,
djangobook.py3k.cn/2.0/chapter12/
11/18
2010-5-5
Django
"socket" => "/home/user/mysite.sock",
"checklocal" => "disable",
)
),
)
alias.url = (
"/media/" => "/home/user/django/contrib/admin/media/",
)
url.rewriteonce = (
"^(/media.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/.*)$" => "/mysite.fcgi$1",
)
lighttpdDjango
lighttpd FastCGIFastCGI
fastcgi.server Django
FastCGI
ApacheDjango
httpd.conf
WebDjango
FastCGI Apache
Web .htaccess
AddHandler fastcgiscript .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
ApacheFastCGI mysite.fcgi
djangobook.py3k.cn/2.0/chapter12/
12/18
2010-5-5
Django
Web
#!/usr/bin/python
import sys, os
# Add a custom Python path.
sys.path.insert(0, "/home/user/python")
# Switch to the directory of your project. (Optional.)
# os.chdir("/home/user/myproject")
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
pythonFastCGI Apache
mysite.fcgi Django
mysite.fcgi
Django
Unix touch
touch mysite.fcgi
DjangoDjango
Apachemod_python
FastCGIApache
20-1
20-1 Django
djangobook.py3k.cn/2.0/chapter12/
13/18
2010-5-5
Django
3000
Web
RAM, CPU
Django DATABASE_HOST
IPDNS IPDNSDNS
20-2
20-2
n-tier Web
Django20-3
djangobook.py3k.cn/2.0/chapter12/
14/18
2010-5-5
Django
20-3
Web lighttpdtux
(http://www.djangoproject.com/r/tux/) Apache
Djangoadmin
MEDIA_ROOT
Django
Django
1000
20-3
Web Django
Apache
load balancer
FastCGIwebFastCGI
FastCGI
Apache/mod_python/Django
20-4
djangobook.py3k.cn/2.0/chapter12/
15/18
2010-5-5
Django
20-4
Web
Web
MySQL
PostgreSQLSlony (http://www.djangoproject.com/r/slony/) pgpool
(http://www.djangoproject.com/r/pgpool/)
round-robinDNS
cachecache
20-5
20-5 Django
djangobook.py3k.cn/2.0/chapter12/
16/18
2010-5-5
Django
Django
Django
Django
RAM
RAM RAM
Web90%IO
RAM
2GB
Web
Keep-Alive
KeepAlive HTTPHTTPTCP
TCPHTTPHTTPTCP
Django
10 HTTPkeep-alive
HTTP
memcached
Djangocache memcached
memcached
memcached
memcached Chapter 15 is your best
friend here: Djangocache
DjangoLinuxApachePostgreSQLMySQL
1%
Django Django
djangobook.py3k.cn/2.0/chapter12/
17/18
2010-5-5
Django
Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter12/
18/18
2010-5-5
HTML
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
HTML
HTML WebHTMLWeb
RSSPDF
HTML Django
DjangoHTML
RSS/Atom
XMLGoogle
MIME
WebWebPython
WebHTML404 XML
Django
HttpRequest
HttpResponse
HTML HttpResponse mimetype
MIME
PNG
open()
HttpResponsePython(API)
PythonHttpResponse
Django CSV
djangobook.py3k.cn/2.0/chapter13/
1/15
2010-5-5
HTML
CSV
CSV
(CSV (comma-separated values) )CSV
CSV CSV
Python CSV csv
csv HttpResponse
import csv
from django.http import HttpResponse
# Number of unruly passengers each year 1995 2005. In a real application
# this would likely come from a database or some other backend data store.
UNRULY_PASSENGERS = [146,184,235,200,226,251,299,273,281,304,203]
def unruly_passengers_csv(request):
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(mimetype='text/csv')
response['ContentDisposition'] = 'attachment; filename=unruly.csv'
# Create the CSV writer using the HttpResponse as the "file."
writer = csv.writer(response)
writer.writerow(['Year', 'Unruly Airline Passengers'])
for (year, num) in zip(range(1995, 2006), UNRULY_PASSENGERS):
writer.writerow([year, num])
return response
djangobook.py3k.cn/2.0/chapter13/
2/15
2010-5-5
HTML
HttpResponseHttpResponse
CSVAPI response csv.writer
csv.writer HttpResponse
writer.writerow list tuple CSV
CSV writerow()
HTML HttpResponse
MIME
PDF
(PDF) Adobe pixel-perfect
2D You can think of a PDF document as the digital equivalent of a printed
document; indeed, PDFs are often used in distributing documents for the purpose of printing them.
Python Django PDF ReportLab
(http://www.reportlab.org/rl_toolkit.html) PDF
PDF The advantage of generating PDF files dynamically is
that you can create customized PDFs for different purposes say, for different users or different pieces
of content.
Django ReportLab KUSports.com NCAA
(tournament brackets)
ReportLab
PDF ReportLab Its usually simple: just
download and install the library from http://www.reportlab.org/downloads.html.
Note
Linux
ReportLab
Ubuntu aptget install pythonreportlab
PDF http://www.reportlab.org/rsrc/userguide.pdf
Python
>>> import reportlab
djangobook.py3k.cn/2.0/chapter13/
3/15
2010-5-5
HTML
PDF
PDF cStringIO PDF
cStringIO C
cStringIO Hello World
from cStringIO import StringIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse
def hello_pdf(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(mimetype='application/pdf')
response['ContentDisposition'] = 'attachment; filename=hello.pdf'
temp = StringIO()
djangobook.py3k.cn/2.0/chapter13/
4/15
2010-5-5
HTML
# Create the PDF object, using the StringIO object as its "file."
p = canvas.Canvas(temp)
# Draw things on the PDF. Here's where the PDF generation happens.
# See the ReportLab documentation for the full list of functionality.
p.drawString(100, 100, "Hello world.")
# Close the PDF object cleanly.
p.showPage()
p.save()
# Get the value of the StringIO buffer and write it to the response.
response.write(temp.getvalue())
return response
Python
Here are a few more ideas and some pointers to libraries you could use to implement them:
ZIP Python zipfile ZIP
TAR tarfile
Python
(http://graphviz.org/) Python
Django The possibilities are immense.
HTML Django
HTML
DjangoRSSAtom feeds
RSS Atom
RSSAtomXMLfeed RSS
http://www.whatisrss.com/, Atom http://www.atomenabled.org/.
(syndication feed)python
(feed)
feed/feeds/DjangoURL(/feeds/)
djangobook.py3k.cn/2.0/chapter13/
5/15
2010-5-5
HTML
feed Django uses the remainder of the URL (everything after /feeds/ ) to determine
which feed to return.
sitemap Sitemap URLconf
feed:
LatestEntries````feeds/latest/ .
LatestEntriesByCategory`` ``feeds/categories/ .
Feed
Feed pythonsyndication feed. feed (
feedblog)(blog
feed category ).
Feeddjango.contrib.syndication.feeds.Feed
Feed
This simple example describes a feed of the latest five blog entries for a given blog:
djangobook.py3k.cn/2.0/chapter13/
6/15
2010-5-5
HTML
:
django.contrib.syndication.feeds.Feed .
title , link , description RSS <title> , <link> , <description> .
RSS2
obj : ( items() )
latest_description.html :
djangobook.py3k.cn/2.0/chapter13/
7/15
2010-5-5
HTML
{{ obj.description }}
Feed
feeds
For example, say your blog offers an RSS feed for every distinct tag youve used to categorize your
entries. Feed
feeds URL
Your tag-specific feeds could use URLs like this:
http://example.com/feeds/tags/python/ : Returns recent entries tagged with python
"beats"
feeds
from django.core.exceptions import ObjectDoesNotExist
from mysite.blog.models import Entry, Tag
class TagFeed(Feed):
def get_object(self, bits):
# In case of "/feeds/tags/cats/dogs/mice/", or other such
# clutter, check that bits has only one member.
if len(bits) != 1:
raise ObjectDoesNotExist
return Tag.objects.get(tag=bits[0])
def title(self, obj):
return "My Blog: Entries tagged with %s" % obj.tag
def link(self, obj):
return obj.get_absolute_url()
def description(self, obj):
return "Entries tagged with %s" % obj.tag
def items(self, obj):
entries = Entry.objects.filter(tags__id__exact=obj.id)
return entries.order_by('pub_date')[:30]
RSSURL /rss/beats/0613/
URL /rss/beats/0613/ URLslug ("/" )
Feed get_object()
['0613'] /rss/beats/0613/foo/bar/ URL
['0613', 'foo', 'bar']
get_object() bits
djangobook.py3k.cn/2.0/chapter13/
8/15
2010-5-5
HTML
In this case, it uses the Django database API to retrieve the Tag . Note that get_object() should raise
django.core.exceptions.ObjectDoesNotExist if given invalid parameters. Beat.objects.get()
1. get_object() obj
2.
3.
(http://www.djangoproject.com/documentation/0.96/syndication_feeds/)
Feed
, RSS 2.0. , Feed feed_type . To change that,
add a feed_type attribute to your Feed class:
from django.utils.feedgenerator import Atom1Feed
class MyFeed(Feed):
feed_type = Atom1Feed
feed_type Feed11-1
11-1. Feed
Feed
django.utils.feedgenerator.Rss201rev2Feed
django.utils.feedgenerator.RssUserland091Feed
RSS 0.91
django.utils.feedgenerator.Atom1Feed
Atom 1.0
djangobook.py3k.cn/2.0/chapter13/
9/15
2010-5-5
HTML
def item_enclosure_url(self, item):
return item.song_url
def item_enclosure_length(self, item):
return item.song_length
item_enclosure_mime_type = "audio/mpeg"
URLs
link /URL "/blog/" URL
"http://www.example.com/blog/" link SITE_ID
URLconf
from django.conf.urls.defaults import *
from myproject.feeds import RssLatestEntries, AtomLatestEntries
feeds = {
'rss': RssLatestEntries,
'atom': AtomLatestEntries,
}
urlpatterns = patterns('',
# ...
(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
{'feed_dict': feeds}),
# ...
djangobook.py3k.cn/2.0/chapter13/
10/15
2010-5-5
HTML
Sitemap
sitemap XML
Django (http://www.djangoproject.com/sitemap.xml)sitemap
<?xml version="1.0" encoding="UTF8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.djangoproject.com/documentation/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>http://www.djangoproject.com/documentation/0_90/</loc>
<changefreq>never</changefreq>
<priority>0.1</priority>
</url>
...
</urlset>
sitemaps , http://www.sitemaps.org/.
Django sitemap Python XML
`` Sitemap`` URLconf
sitemap , :
1. 'django.contrib.sitemaps' INSTALLED_APPS .
2. 'django.template.loaders.app_directories.load_template_source' TEMPLATE_LOADERS
, , ,
3. sites (14).
Note
sitemap . INSTALLED_APPS :
load_template_source . The only reason it needs to go into
INSTALLED_APPS is so the load_template_source template loader can find the default templates.
Initialization
Djangositemap, URLconf :
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
This line tells Django to build a sitemap when a client accesses /sitemap.xml . Note that the dot
character in sitemap.xml is escaped with a backslash, because dots have a special meaning in regular
expressions.
sitemap sitemapURL
djangobook.py3k.cn/2.0/chapter13/
11/15
2010-5-5
HTML
sitemap.xml URL
sitemap /content/sitemap.xml /content/ URL
sitemap {'sitemaps': sitemaps} . sitemaps should be a dictionary that
maps a short section label (e.g., blog or news ) to its Sitemap class (e.g., BlogSitemap or NewsSitemap ). It
may also map to an instance of a Sitemap class (e.g., BlogSitemap(some_var) ).
Sitemap
Sitemap Python., Sitemap
For example, one Sitemap class could represent all the entries of your
weblog, while another could represent all of the events in your events calendar.
sitemap.xml
Sitemap django.contrib.sitemaps.Sitemap .
Sitemap Feed
Feed Sitemap
Sitemap /:
items ( )
location()
: '/foo/bar/' '/foo/bar/'
: 'example.com/foo/bar/' 'example.com/foo/bar/'
Bad: 'http://example.com/foo/bar/'
djangobook.py3k.cn/2.0/chapter13/
12/15
2010-5-5
HTML
'hourly'
'daily'
'weekly'
'monthly'
'yearly'
'never'
sitemap
FlatPageSitemap
django.contrib.sitemaps.FlatPageSitemap flat pagesitemap
GenericSitemap
GenericSitemap 9
info_dict queryset
date_field queryset lastmod
djangobook.py3k.cn/2.0/chapter13/
13/15
2010-5-5
HTML
'blog': GenericSitemap(info_dict, priority=0.6),
}
urlpatterns = patterns('',
# some generic view using info_dict
# ...
# the sitemap
(r'^sitemap\.xml$',
'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps})
)
Sitemap
sitemap sitemaps sitemap
URLconf : django.contrib.sitemaps.views.index
django.contrib.sitemaps.views.sitemap . `` django.contrib.sitemaps.views.index`` ``
django.contrib.sitemaps.views.sitemap``
django.contrib.sitemaps.views.sitemap section .
URLconf :
(r'^sitemap.xml$',
'django.contrib.sitemaps.views.index',
{'sitemaps': sitemaps}),
(r'^sitemap(?P<section>.+).xml$',
'django.contrib.sitemaps.views.sitemap',
{'sitemaps': sitemaps})
Google
sitemapGoogle
django.contrib.sitemaps.ping_google()
ping_google() sitemap_url URL
djangobook.py3k.cn/2.0/chapter13/
14/15
2010-5-5
HTML
pass
, Django ` <../chapter14/>`__
sessions, users authentication.
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter13/
15/15
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Web
()
HTTP
(IP)
(cookies)
Cookies
HTTPs Web
(cookies) cookies Web
cookies
google.com GoogleHTTP
GET / HTTP/1.1
Host: google.com
...
GoogleHTTP
HTTP/1.1 200 OK
ContentType: text/html
SetCookie: PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671;
expires=Sun, 17Jan2038 19:14:07 GMT;
path=/; domain=.google.com
Server: GWS/2.1
...
SetCookie cookie(
PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671 ) google
cookie Google
GET / HTTP/1.1
Host: google.com
Cookie: PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671
...
Cookies GoogleGoogle
key Google
djangobook.py3k.cn/2.0/chapter14/
1/17
2010-5-5
Cookies
Djangosession / user
cookies
cookies
cookies `` HttpRequest`` `` COOKIES``
viewcookies
def show_color(request):
if "favorite_color" in request.COOKIES:
return HttpResponse("Your favorite color is %s" %
request.COOKIES["favorite_co
else:
return HttpResponse("You don't have a favorite color.")
cookie
def set_color(request):
if "favorite_color" in request.GET:
# Create an HttpResponse object...
response = HttpResponse("Your favorite color is now %s" %
request.GET["favorit
response.set_cookie() cookie14-1
System Message: ERROR/3 (<string>, line 145)
Error parsing content block for the table directive: exactly one table expected.
.. table:: 141: Cookie
+++
|
|
|
+=================================+===========================+================================
|``None``
|cookie
+++
|``max_age``
|``expires``
|``None``
|cookie/
+++
|``path``
|``"/"``
|cookie co
|
+++
|``domain``
|
|``None``
|
|cookie
|
|
|\ `` None`` coo
+++
|
|``False``
djangobook.py3k.cn/2.0/chapter14/
|``False``
| ``True`` HT
2/17
2010-5-5
+++
Cookies
cookies
cookiecookie
cookies cookiesWeb
cookies cookies
cookie
Cookie(HTTPS) HTTP
cookies cookies
cookie
cookie 19
cookie cookies
mechanize(http://wwwsearch.sourceforge.net/mechanize/)
HTTP
cookies cookies IsLoggedIn=1
Django Session
cookiesWeb Django
session
1
session cookie
CookiesIDcookie
session
Sessions
Sessions (17)(model) sessions
1. MIDDLEWARE_CLASSES MIDDLEWARE_CLASSES
'django.contrib.sessions.middleware.SessionMiddleware'
2. INSTALLED_APPS 'django.contrib.sessions' (
manage.py syncdb )
startproject
session
session MIDDLEWARE_CLASSES SessionMiddleware INSTALLED_APPS
djangobook.py3k.cn/2.0/chapter14/
3/17
2010-5-5
'django.contrib.sessions'
Session
SessionMiddleware (view)``HttpRequest`` session
(view)
# Set a session value:
request.session["fav_color"] = "blue"
# Get a session value this could be called in a different view,
# or many requests later (or both):
fav_color = request.session["fav_color"]
# Clear an item from the session:
del request.session["fav_color"]
# Check if the session has a given key:
if "fav_color" in request.session:
...
request.session Python
has_commented
True
def post_comment(request):
if request.method != 'POST':
raise Http404('Only POSTs are allowed')
if 'comment' not in request.POST:
raise Http404('Comment not submitted')
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=request.POST['comment'])
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')
djangobook.py3k.cn/2.0/chapter14/
4/17
2010-5-5
(view)
def login(request):
if request.method != 'POST':
raise Http404('Only POSTs are allowed')
try:
m = Member.objects.get(username=request.POST['username'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponseRedirect('/youareloggedin/')
except Member.DoesNotExist:
return HttpResponse("Your username and password didn't match.")
`` login()``
def logout(request):
try:
del request.session['member_id']
except KeyError:
pass
return HttpResponse("You're logged out.")
(authentication )
Cookies
cookie Django
cookie (view) request.session.set_test_cookie()
(view)(view) request.session.test_cookie_worked()
set_test_cookie() test_cookie_worked() cookie
cookie
cookie
cookie delete_test_cookie()
cookie
def login(request):
# If we submitted the form...
if request.method == 'POST':
# Check that the test cookie worked (we set it below):
if request.session.test_cookie_worked():
# The test cookie worked, so delete it.
request.session.delete_test_cookie()
# In practice, we'd need some logic to check username/password
# here, but since this is an example...
return HttpResponse("You're logged in.")
djangobook.py3k.cn/2.0/chapter14/
5/17
2010-5-5
# The test cookie failed, so display an error message. If this
# were a real site, we'd want to display a friendlier message.
else:
return HttpResponse("Please enable cookies and try again.")
# If we didn't post, send the test cookie along with the login form.
request.session.set_test_cookie()
return render_to_response('foo/login_form.html')
(View)Session
sessionDjango model django.contrib.sessions.models )
session32cookie
DjangoAPIsession
>>> from django.contrib.sessions.models import Session
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s.expire_date
datetime.datetime(2005, 8, 20, 13, 35, 12)
get_decoded() session
>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
>>> s.get_decoded()
{'user_id': 42}
Session
Djangosession
# Session is modified.
request.session['foo'] = 'bar'
# Session is modified.
del request.session['foo']
# Session is modified.
request.session['foo'] = {}
# Gotcha: Session is NOT modified, because this alters
# request.session['foo'] instead of request.session.
request.session['foo']['bar'] = 'baz'
vs
Googlecookie expires=Sun, 17Jan2038 19:14:07 GMT; cookie
djangobook.py3k.cn/2.0/chapter14/
6/17
2010-5-5
cookie cookie
cookie SESSION_EXPIRE_AT_BROWSER_CLOSE session
Session
Django sessioncookie 14-2.
14-2. cookie
SESSION_COOKIE_DOMAIN
cookiesession cookies
None
cookie
SESSION_COOKIE_SECURE
"sessionid"
session
session Python Pythonpickle
Session django_session
Session request.session Django
Django cookie
cookie( SESSION_SAVE_EVERY_REQUEST True )
Django session cookie IDURL
(PHP,JSP)
sessionURL
Referer headersession ID
django.contrib.sessions
Authentication
session session
Django Django
cookie auth/auth ()
djangobook.py3k.cn/2.0/chapter14/
7/17
2010-5-5
1. () ()
2.
()
Django /
:
: (yes/no)
:
Messages :
admin(6)admin
1. session cookiesesson
3. SessionMiddleware MIDDLEWARE_CLASSES
'django.contrib.auth.middleware.AuthenticationMiddleware' SessionMiddleware
User
User request.user
AnonymousUser
user
14-3. User
username
30
first_name
; 30
djangobook.py3k.cn/2.0/chapter14/
8/17
2010-5-5
last_name
; 30
password
is_staff
is_active
. False
is_superuser
last_login
date_joined
+=============================================================================================+
|``is_authenticated()``
|
|
++
|``is_anonymous()``
++
|``get_full_name()``
|
++
|``set_password(passwd)``
++
|check_password(passwd)
++
|``get_group_permissions()``
|
++
|``get_all_permissions()``
++
|``has_perm(perm)``
++
|has_perms(perm_list)
|
++
|``has_module_perms(app_label)``
++
|get_and_delete_messages()
++
|``email_user(subj, msg)``
|
++
djangobook.py3k.cn/2.0/chapter14/
9/17
2010-5-5
Django (view) ()
Djangodjango.contrib.auth\ : authenticate()
login()
authenticate() username
password User authenticate()
None
>>> from django.contrib import auth
>>> user = auth.authenticate(username='john', password='secret')
>>> if user is not None:
...
print "Correct!"
... else:
...
authenticate() login()
HttpRequest User Django session ID
authenticate() login()
from django.contrib import auth
def login_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
# Correct password, and the user is marked "active"
auth.login(request, user)
# Redirect to a success page.
return HttpResponseRedirect("/account/loggedin/")
else:
# Show an error page
return HttpResponseRedirect("/account/invalid/")
django.contrib.auth.logout() HttpRequest
logout()
djangobook.py3k.cn/2.0/chapter14/
10/17
2010-5-5
/
URLconf
from django.contrib.auth.views import login, logout
urlpatterns = patterns('',
# existing patterns here...
(r'^accounts/login/$',
login),
(r'^accounts/logout/$', logout),
)
/accounts/login/ /accounts/logout/ DjangoURL
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p class="error">Sorry, that's not a valid username or password</p>
{% endif %}
<form action="" method="post">
<label for="username">User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next|escape }}" />
</form>
{% endblock %}
/accounts/profile URLnext
GETnext
logout registration/logged_out.html
next_page
request.user.is_authenticated() ,
from django.http import HttpResponseRedirect
def my_view(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/?next=%s' % request.path)
# ...
djangobook.py3k.cn/2.0/chapter14/
11/17
2010-5-5
def my_view(request):
if not request.user.is_authenticated():
return render_to_response('myapp/login_error.html')
# ...
, login_required :
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
# ...
login_required :
login
request.user
polls.can_vote
def vote(request):
if request.user.is_authenticated() and request.user.has_perm('polls.can_vote')):
# vote here
else:
return HttpResponse("You can't vote in this poll.")
Django user_passes_test
def user_can_vote(user):
return user.is_authenticated() and user.has_perm("polls.can_vote")
@user_passes_test(user_can_vote, login_url="/login/")
def vote(request):
# Code here can assume a loggedin user with the correct permission.
...
user_passes_test User
True user_passes_test User
login_url URL
/accounts/login/ user_passes_test login_url
Django
permission_required()
from django.contrib.auth.decorators import permission_required
djangobook.py3k.cn/2.0/chapter14/
12/17
2010-5-5
@permission_required('polls.can_vote', login_url="/login/")
def vote(request):
# ...
Django
URLconf
from django.contrib.auth.decorators import login_required
from django.views.generic.date_based import object_detail
@login_required
def limited_object_detail(*args, **kwargs):
return object_detail(*args, **kwargs)
, login_required
API
create_user :
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user(username='john',
...
email='jlennon@beatles.com',
...
password='glass onion')
set_password()
>>> user = User.objects.get(username='john')
>>> user.set_password('goo goo goo joob')
>>> user.save()
password salthash
User password
hashtype$salt$hash
djangobook.py3k.cn/2.0/chapter14/
13/17
2010-5-5
salt$
hashtype sha1 md5 Salt
:
sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4
User.set_password() User.check_password()
salt
rainbow tables
rainbow tables
hash salt
saltrainbow table
salthash
Django
, , Django
, :
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/books/")
else:
form = UserCreationForm()
return render_to_response("registration/register.html", {
'form': form,
})
registration/register.html
{% extends "base.html" %}
djangobook.py3k.cn/2.0/chapter14/
14/17
2010-5-5
RequestContext context9
RequestContext TEMPLATE_CONTEXT_PROCESSORS
django.core.context_processors.auth
context TEMPLATE_CONTEXT_PROCESSORS "django.core.context_processors.auth"
context
RequestContext , ( User AnonymousUser )
{{ user }} :
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
{{ perms }}
perms {{ perms.polls }}
{{ perms.polls.can_vote }}
{% if %} :
{% if perms.polls %}
<p>You have permission to do something in the polls app.</p>
{% if perms.polls.can_vote %}
<p>You can vote!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the polls app.</p>
{% endif %}
Djangoadmin
djangobook.py3k.cn/2.0/chapter14/
15/17
2010-5-5
Djangoadmin
add
change
delete
Mary
MaryID
'Special users'
VIPVIP
admin Django
django.contrib.auth.models DjangoAPI
User
Djangoadmin
admin The object was created successfully
API API
user.message_set.create(message='message_text')
/ user.get_and_delete_messages() Message
playlist
def create_playlist(request, songs):
# Create the playlist with the given songs.
djangobook.py3k.cn/2.0/chapter14/
16/17
2010-5-5
# ...
request.user.message_set.create(
message="Your playlist was added successfully."
)
return render_to_response("playlists/create.html",
context_instance=RequestContext(request))
RequestContext {{ messages }}
context
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
RequestContext get_and_delete_messages
` <../chapter15/>`__ Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter14/
17/17
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
washingtonpost.com
Slashdot
Django
Django
DjangoSquid(http://www.squid-cache.org)
(HTTP)
MemcachedDjangoMemcached
LiveJournal.comDanga Interactive
Facebook
Memcachedhttp://danga.com/memcached
djangobook.py3k.cn/2.0/chapter15/
1/12
2010-5-5
MemcachedMemcached PythonDjango
cmemcachehttp://gijsbert.org/cmemcache
cmemcachepython - Memcached
ftp://ftp.tummy.com/pub/python-memcached/Memcached
http://www.danga.com/memcached/APIPython
MemcachedDjangoCACHE_BACKENDmemcached/ / IPport/IP
MemcachedIPportMemcached
Memcached (127.0.0.1),11211
CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
Memcached
Memcached
CACHE_BACKEND
IP172.19.26.240172.19.26.24211211Memcached
:
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
172.19.26.240(11211)172.19.26.242(11212)172.19.26.244(
11213)Memcached:
CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11212;172.19.26.244:11213/'
Memcached
Django
[cache_table_name]
Django
CACHE_BACKENDdb://tablenametablename
my_cache_table:
my_cache_table
CACHE_BACKEND = 'db://my_cache_table'
1
settings .
djangobook.py3k.cn/2.0/chapter15/
2/12
2010-5-5
CACHE_BACKENDfile://
/var/tmp/django_cache
CACHE_BACKEND = 'file:///var/tmp/django_cache'
file:///var/tmp/django_cache
Windowsfile://
file://c:/foo/bar
**
Web
apache/var/tmp/django_cacheapache
/var/tmp/django_cache
Pythonpickle(pickled)
Memcached
CACHE_BACKEND locmem:/// :
CACHE_BACKEND = 'locmem:///'
Django
/
CACHE_BACKEND
CACHE_BACKEND = 'dummy:///'
Django Django
Python importCACHE_BACKEND URI
CACHE_BACKEND = 'path.to.backend://'
Django
django/core/cache/backends/
Django
djangobook.py3k.cn/2.0/chapter15/
3/12
2010-5-5
CACHE_BACKEND
CACHE_BACKEND
timeout : 300
max_entries
300
cull_percentage : max_entries , 1/cull_percentage ,
cull_frequency=2 max_entries
cull_frequency 0 max_entries ,
,
timeout 60
CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=60"
Cache
django.middleware.cache.UpdateCacheMiddleware
django.middleware.cache.FetchFromCacheMiddlewareMIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
fectch
MIDDLEWARE_CLASSES
Django settings
CACHE_MIDDLEWARE_SECONDS :
CACHE_MIDDLEWARE_KEY_PREFIX Django
Djangokey
GETPOST
djangobook.py3k.cn/2.0/chapter15/
4/12
2010-5-5
CACHE_MIDDLEWARE_ANONYMOUS_ONLYTrue
user-specific pagesDjangos
CACHE_MIDDLEWARE_ANONYMOUS_ONLY
AuthenticationMiddleware
HttpResponse
()Last-Modified/
Expires/CACHE_MIDDLEWARE_SECONDS
Cache-ControlCACHE_MIDDLEWARE_SECONDS
17
CacheControl
CACHE_MIDDLEWARE_SECONDSdjango.views.decorators.cache
cache_controlnever_cache
django.views.decorators.cache
cache_page :
from django.views.decorators.cache import cache_page
def my_view(request):
# ...
my_view = cache_page(my_view, 60 * 15)
Python2.4
@cache_page(60 * 15)
def my_view(request):
# ...
cache_page my_view() 15
60 * 15 60 * 15 900 15
60
URL URL
my_view URLconf
urlpatterns = ('',
(r'^foo/(\d{1,2})/$', my_view),
)
/foo/1/ /foo/23/
/foo/23/ URL
djangobook.py3k.cn/2.0/chapter15/
5/12
2010-5-5
URLconf
cache_page my_view
URLconf
URLconf cache_page
URLconf : URLconf
urlpatterns = ('',
(r'^foo/(\d{1,2})/$', my_view),
)
, URLconf cache_page
{% cache %} :
{% load cache %}
{% cache 500 sidebar %}
.. sidebar ..
{% endcache %}
{% cache %}
{% load cache %}
{% cache 500 sidebar request.user.username %}
.. sidebar for logged in user ..
{% endcache %}
{% cache %}
my_timeout600
API
djangobook.py3k.cn/2.0/chapter15/
6/12
2010-5-5
DjangoAPI API
pickle Python
Python pickling
django.core.cacheCACHE_BACKENDdjango.core.cache
>>> from django.core.cache import cache
cache.get()None
# Wait 30 seconds for 'my_key' to expire...
>>> cache.get('my_key')
None
cache.get()
>>> cache.get('my_key', 'has expired')
'has expired'
add() set()
add() TrueFalse
get_many() get_many()
>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}
, cache.delete()
>>> cache.delete('a')
djangobook.py3k.cn/2.0/chapter15/
7/12
2010-5-5
incr()decr() 1
ValueError
>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12
>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6
Web
ISP () http://example.com/
ISP example.com example.com
ISP example.com
Django Squid (http://www.squidcache.org/)
URL
ISP
ISP
HTTP HTTP
Vary
Vary
djangobook.py3k.cn/2.0/chapter15/
8/12
2010-5-5
Django "/stories/2005/jun/23/bank_robbed/"
cookie
Varycookie
Django vary_on_headers
from django.views.decorators.vary import vary_on_headers
# Python 2.3 syntax.
def my_view(request):
# ...
my_view = vary_on_headers(my_view, 'UserAgent')
# Python 2.4+ decorator syntax.
@vary_on_headers('UserAgent')
def my_view(request):
# ...
Django
vary_on_headers()
@vary_on_headers('UserAgent', 'Cookie')
def my_view(request):
# ...
user-agent cookie
Mozilla user-agent foo=bar cookie Mozilla
user-agent foo=ham
cookie vary_on_cookie
@vary_on_cookie
def my_view(request):
# ...
@vary_on_headers('Cookie')
def my_view(request):
# ...
djangobook.py3k.cn/2.0/chapter15/
9/12
2010-5-5
patch_vary_headers HttpResponse
Web
Django cache_control
from django.views.decorators.cache import cache_control
@cache_control(private=True)
def my_view(request):
# ...
HTTP
, HTTP :
private=True
no_cache=True
no_transform=True
must_revalidate=True
proxy_revalidate=True
djangobook.py3k.cn/2.0/chapter15/
10/12
2010-5-5
max_age=num_seconds
s_maxage=num_seconds
Django :
django.middleware.http.ConditionalGetMiddleware ETag
LastModified GET
django.middleware.gzip.GZipMiddleware
MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES
Vary
UpdateCacheMiddleware last
UpdateCacheMiddlewareVary
Cookie SessionMiddleware
AcceptEncoding GZipMiddleware
AcceptLanguageLocaleMiddleware
FetchFromCacheMiddleware
FetchFromCacheMiddlewareVary
FetchFromCacheMiddleware
Django adminsession/user
Django
djangobook.py3k.cn/2.0/chapter15/
11/12
2010-5-5
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter15/
12/12
2010-5-5
django.con
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
django.contrib
Python Python
Django
Django
Django django.contrib
django.contrib
django.contrib
Django
django.contrib
django.contrib
admin : 6
auth : Django
comments :
Django.
Django
contenttypes : Django
DjangoDjango
django/contrib/contenttypes/
csrf : (CSRF) CSRF
djangobook.py3k.cn/2.0/chapter16/
1/15
2010-5-5
django.con
formtools Django
Django
http://geodjango.org/
humanize : Django
localflavor
markup : Django
redirects :
sessions : Django 14
sitemaps : XML 13
sites : Django
Django
django.contrib
Django Django
1
Django LJWorld.com Lawrance.com
LJWorld.com Lawrence.com
LJWorld.comLawrence.com
Django
djangobook.py3k.cn/2.0/chapter16/
2/15
2010-5-5
django.con
2/
LJWorld.com Lawrence.com
Site name ( 'LJWorld.com' )
domain ( 'www.ljworld.com' )
django.contrib.sites Site domain name
SITE_ID Site ID
Django
1. 'django.contrib.sites' INSTALLED_APPS
2. manage.py syncdb django_site
example.com
3. example.com Django adminPython APISite
Django Site
4. SITE_ID Site
ID
, Site
from django.db import models
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(max_length=200)
# ...
sites = models.ManyToManyField(Site)
Django Article article_detail
djangobook.py3k.cn/2.0/chapter16/
3/15
2010-5-5
django.con
SITE_ID articles
LJWorld.coms SITE_ID 1 Lawrence.coms SITE_ID
2 LJWorld.coms
LJWorld.com
Site
Django
from django.conf import settings
def my_view(request):
if settings.SITE_ID == 3:
# Do something.
else:
# Do something else.
ID
from django.conf import settings
from django.contrib.sites.models import Site
def my_view(request):
current_site = Site.objects.get(id=settings.SITE_ID)
if current_site.domain == 'foo.com':
# Do something
else:
# Do something else.
djangobook.py3k.cn/2.0/chapter16/
4/15
2010-5-5
django.con
current_site = Site.objects.get_current()
if current_site.domain == 'foo.com':
# Do something
else:
# Do something else.
django.conf.settings
DRY()
Site name domain
from django.contrib.sites.models import Site
from django.core.mail import send_mail
def register_for_newsletter(request):
# Check form values, etc., and subscribe the user.
# ...
current_site = Site.objects.get_current()
send_mail('Thanks for subscribing to %s alerts' % current_site.name,
'Thanks for your subscription. We appreciate it.\n\nThe %s team.' % current_site.name,
'editor@%s' % current_site.domain,
[user_email])
# ...
Django Lawrence.com
LJWorld.com TEMPLATE_DIRS
from django.core.mail import send_mail
from django.template import loader, Context
def register_for_newsletter(request):
# Check form values, etc., and subscribe the user.
# ...
subject = loader.get_template('alerts/subject.txt').render(Context({}))
message = loader.get_template('alerts/message.txt').render(Context({}))
send_mail(subject, message, 'donotreply@example.com', [user_email])
# ...
CurrentSiteManager
CurrentSiteManager
from django.db import models
djangobook.py3k.cn/2.0/chapter16/
5/15
2010-5-5
django.con
Photo.objects.filter(site=settings.SITE_ID)
Photo.on_site.all()
CurrentSiteManager Photo Site site
site CurrentSiteManager
publish_on
from django.db import models
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(max_length=100)
pub_date = models.DateField()
publish_on = models.ForeignKey(Site)
objects = models.Manager()
on_site = CurrentSiteManager('publish_on')
CurrentSiteManager
B Django
objects = models.Manager()
Django Django
CurrentSiteManager
objects = models.Manager()
Django
Django
Django domain name SITE_ID
ID
Django
Django
SITE_ID
djangobook.py3k.cn/2.0/chapter16/
6/15
2010-5-5
django.con
site SITE_ID
Flatpages()
Web
Apache Web
Apache
Django
django.contrib.flatpages Django flatpages
Django Django
Django
DjangoAPI
URL URL
django.contrib.sitesINSTALLED_APPS
2. 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware' MIDDLEWARE_CLASSES
3. manage.py syncdb
FlatPage django/contrib/flatpages/models.py
from django.db import models
from django.contrib.sites.models import Site
djangobook.py3k.cn/2.0/chapter16/
7/15
2010-5-5
django.con
class FlatPage(models.Model):
url = models.CharField(max_length=100, db_index=True)
title = models.CharField(max_length=200)
content = models.TextField(blank=True)
enable_comments = models.BooleanField()
template_name = models.CharField(max_length=70, blank=True)
registration_required = models.BooleanField()
sites = models.ManyToManyField(Site)
title :
content : ( HTML )
enable_comments :
template_name :
flatpages/default.html
registration_required : Djangos /
sites : Django
flatpages/default.html flatpage
RequestContext
FlatpageFallbackMiddleware
404 500
MIDDLEWARE_CLASSES FlatpageFallbackMiddleware
djangobook.py3k.cn/2.0/chapter16/
8/15
2010-5-5
django.con
Django Flatpages
Python API
django/contrib/flatpages/models.py Django
DjangoAPI
>>> from django.contrib.flatpages.models import FlatPage
>>> from django.contrib.sites.models import Site
>>> fp = FlatPage.objects.create(
...
...
url='/about/',
title='About',
...
...
enable_comments=False,
...
template_name='',
...
registration_required=False,
... )
>>> fp.sites.add(Site.objects.get(id=1))
>>> FlatPage.objects.get(url='/about/')
<FlatPage: /about/ About>
flatpages/default.html FlatPage
template_name
flatpages/default.html flatpages
default.html
flatpage
flatpages/default.html :
<!DOCTYPE HTML PUBLIC "//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REChtml40/loose.dtd">
<html>
<head>
<title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content|safe }}
</body>
</html>
safeflatpage.contentHTML
Django Django
Django /music/ /sections/arts/music/
djangobook.py3k.cn/2.0/chapter16/
9/15
2010-5-5
django.con
1. 'django.contrib.redirects' INSTALLED_APPS
2. 'django.contrib.redirects.middleware.RedirectFallbackMiddleware' MIDDLEWARE_CLASSES
3. manage.py syncdb
manage.py syncdb django_redirect site_id
old_pathnew_path
Django Django API
new_path new_path
new_path 410 (Gone) HTTP
404 500
MIDDLEWARE_CLASSES RedirectFallbackMiddleware
Django
Python API
django/contrib/redirects/models.py Django Django
API
djangobook.py3k.cn/2.0/chapter16/
10/15
2010-5-5
django.con
site=Site.objects.get(id=1),
old_path='/music/',
...
new_path='/sections/arts/music/',
... )
>>> Redirect.objects.get(old_path='/music/')
<Redirect: /music/ > /sections/arts/music/>
CSRF
django.contrib.csrf (CSRF).
CSRF,
URL
CSRF
example.com example.com/logout
example.com/logout
URL example.com/logout <iframe> , URL
example.com example.com/logout <iframe>
example.com Thus, if youre logged in to the example.com
webmail account and visit the malicious page that has an <iframe> to example.com/logout , the act of
visiting the malicious page will log you out from example.com .
CSRF
example.com HTTP GET
HTTP POST
POST CSRF
example.com/logoutPOST POST
example.com/logout truePOST confirm
CSRF
<iframe> Javascript
CSRF
GET
<iframe>
djangobook.py3k.cn/2.0/chapter16/
11/15
2010-5-5
django.con
CSRF
django.contrib.csrf middleware.py Django
CsrfMiddleware CSRF
'django.contrib.csrf.middleware.CsrfMiddleware' MIDDLEWARE_CLASSES
CSRF SessionMiddleware CsrfMiddleware
SessionMiddleware
CsrfMiddleware GZipMiddleware
MIDDLEWARE_CLASSES MIDDLEWARE_CLASSES
CsrfMiddleware
1. POST csrfmiddlewaretoken
ID ID
POST
HTTP POST POST
GET
cookie POST
HTML ContentType
text/html application/xml+xhtml
CSRF
CsrfMiddleware Django 14
cookies
HTML Javascript document.write
HTML
CsrfMiddlewarecsrfmiddlewaretokenHTML
HTML
csrfmiddlewaretoken
CSRF http://en.wikipedia.org/wiki/CSRF
djangobook.py3k.cn/2.0/chapter16/
12/15
2010-5-5
django.con
django.contrib.humanize
'django.contrib.humanize'INSTALLED_APPS
{% load humanize %}
apnumber
1 9
1 one
2 two
10 10
intcomma
4500 4,500
45000 45,000
450000 450,000
4500000 4,500,000
intword
djangobook.py3k.cn/2.0/chapter16/
13/15
2010-5-5
django.con
ordinal
1 1st
2 2nd
3 3rd
254254th
django.contrib.markupDjango
textile : Textile (http://en.wikipedia.org/wiki/Textile_%28markup_language%29)
textile
TextileHTML
{% load markup %}
{{ object.content|textile }}
'django.contrib.markup' INSTALLED_APPS
{% load markup %}
django/contrib/markup/templatetags/markup.py.
CSRF /
Django
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter16/
14/15
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Djangorequest view
request
DjangoDjangorequest/response
plug-inDjango
12sessionuser(view
request.session request.user )
13cacheviewresponse
view
14 flatpages , redirects , csrf
Djangoproxy(20)
requestIP(request.META["REMOTE_IP"] )proxy
requestIP proxy XForwardedFor IP
proxy request.META["REMOTE_ADDR"]
IP
class SetRemoteAddrFromForwardedFor(object):
def process_request(self, request):
try:
real_ip = request.META['HTTP_X_FORWARDED_FOR']
except KeyError:
pass
else:
# HTTP_X_FORWARDED_FOR can be a commaseparated list of IPs.
# Take just the first one.
real_ip = real_ip.split(",")[0]
request.META['REMOTE_ADDR'] = real_ip
(Note: Although the HTTP header is called XForwardedFor , Django makes it available as
request.META['HTTP_X_FORWARDED_FOR'] . With the exception of contentlength and contenttype , any
HTTP headers in the request are converted to request.META keys by converting all characters to
uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name.)
djangobook.py3k.cn/2.0/chapter17/
1/6
2010-5-5
()request XForwardedFor
request.META['REMOTE_ADDR'] Djangoproxy
request.META['REMOTE_ADDR'] proxy
Django django.middleware.http ,
,
MIDDLEWARE_CLASSES MIDDLEWARE_CLASSES
Python djangoadmin.py startproject
MIDDLEWARE_CLASSES :
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
Django MIDDLEWARE_CLASSES
requestviewDjango MIDDLEWARE_CLASSES
responseDjango Django
MIDDLEWARE_CLASSES view requestresponse
middleware
__init__() self
djangobook.py3k.cn/2.0/chapter17/
2/6
2010-5-5
None , Djangorequest, view.
HttpResponse , Django ()view
Django HttpResponse .
15-1View
15-1. process_view()
request
view
view
request ( view)
kwargs
view.
Just like process_request() , process_view() should return either None or an HttpResponse object.
If it returns None , Django will continue processing this request, executing any other middleware
and then the appropriate view.
If it returns an HttpResponse object, Django wont bother calling any other middleware (of any
type) or the appropriate view. Django will immediately return that HttpResponse .
djangobook.py3k.cn/2.0/chapter17/
3/6
2010-5-5
,
request view exception
process_exception() None HttpResponse .
None , Djangorequest
HttpResponse , Django response
Django()
Djangos wiki:
http://code.djangoproject.com/wiki/ContributedMiddleware
http://code.djangoproject.com/wiki/ContributedMiddleware
Django
: django.contrib.auth.middleware.AuthenticationMiddleware .
django.contrib.auth.middleware.AuthenticationMiddleware .
. HttpRequest request.user
It adds the request.user attribute, representing the currently logged-in user, to every incoming
HttpRequest object.
12
import re
DISALLOWED_USER_AGENTS = (
re.compile(r'^OmniExplorer_Bot'),
re.compile(r'^Googlebot')
)
djangobook.py3k.cn/2.0/chapter17/
4/6
2010-5-5
``APPEND_SLASH`` ``PREPEND_WWW`` URL APPEND_SLASH True ,
URLURLpath
foo.com/bar foo.com/bar/ , foo.com/bar/file.txt
Not Modified (
GET , Etags
django.middleware.gzip.GZipMiddleware .
gzip()] Web
GET
Middleware class: django.middleware.http.ConditionalGetMiddleware .
GET response LastModified ETag request
IfNoneMatch IfModifiedSince responseresponse 304(Not
modified) ETag USE_ETAGS response ETag
response ETag As discussed above, the ETag header is set by the Common
middleware.
HEAD requestresponserequestresponse
Date ContentLength
(X-Forwarded-For)
Middleware class: django.middleware.http.SetRemoteAddrFromForwardedFor .
request.META['HTTP_X_FORWARDED_FOR']
request.META['REMOTE_ADDR'] request
REMOTE_ADDR 127.0.0.1 It sets request.META['REMOTE_ADDR']
middleware HTTP_X_FORWARDED_FOR
HTTP_X_FORWARDED_FOR
djangobook.py3k.cn/2.0/chapter17/
5/6
2010-5-5
Django 13
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter17/
6/6
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Djangogreen-field
Django
inspectdb
inspectdb DjangoPython
Django
mysite/myapp/models.py models
Models
models :
model (model )
models ManyToManyField
djangobook.py3k.cn/2.0/chapter18/
1/5
2010-5-5
modelid model
Djangoid
id = models.IntegerField(primary_key=True)
CharFieldDateField VARCHAR,DATE
inspectdbmodelTextField
modelPython
Django Django
Pythonpassclassforinspectdb
_fielddb_columnpass,classfor
INTformodel
for_field = models.IntegerField(db_column='for')
inspectdb Python
model
model Bookmodel Author
modelmodel
model
PostgreSQL,MySQLSQLiteinspectdb
primary_key=True model
Djangomodelprimary_key=True
PostgreSQLMySQL
INTIntegerField
Django
LDAP
LDAPDjango
Django Diango
Django django.contrib.auth.authenticate()
(14)Django Django
djangobook.py3k.cn/2.0/chapter18/
2/5
2010-5-5
AUTHENTICATION_BACKENDS Python
Python Python
AUTHENTICATION_BACKENDS
('django.contrib.auth.backends.ModelBackend',)
Django
AUTHENTICATION_BACKENDSDjango
get_user(id) authenticate(**credentials)
get_user id id ID
User
authenticate
class MyBackend(object):
def authenticate(self, username=None, password=None):
# Check the username/password and return a User.
class MyBackend(object):
def authenticate(self, token=None):
# Check the token and return a User.
authenticate
User None None
14Django User
LDAPSQLDjango User
authenticate
setting.py usernamepassword
Django User
from django.conf import settings
from django.contrib.auth.models import User, check_password
class SettingsBackend(object):
"""
Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
Use the login name, and a hash of the password. For example:
ADMIN_LOGIN = 'admin'
ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
"""
def authenticate(self, username=None, password=None):
login_valid = (settings.ADMIN_LOGIN == username)
pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
if login_valid and pwd_valid:
djangobook.py3k.cn/2.0/chapter18/
3/5
2010-5-5
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
# Create a new user. Note that we can set password
# to anything, because it won't be checked; the password
# from settings.py will.
user = User(username=username, password='get from settings.py')
user.is_staff = True
user.is_superuser = True
user.save()
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
, Django
Web
WebDjango
Apacheshttpd.confURL 12
Apache/mod_pythonDjango12
)
httpd.confDjangoURL
12Django
<Location "/">
SetHandler pythonprogram
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonDebug On
</Location>
/admin/URLDjango
djangobook.py3k.cn/2.0/chapter18/
4/5
2010-5-5
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter18/
5/5
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | | |
Django40 Djano
Django
*
I18N(18InternationlizationIN18)
*
L10N
Django
Django50 Django
Python * *
Django
DjangoWeb
Django
DjangoWeb
:
Django GNU gettext (http://www.gnu.org/software/gettext/)Python
gettext
:
DjangoDjango
USE_I18N = False USE_I18N False Django
TEMPLATE_CONTEXT_PROCESSORS 'django.core.context_processors.i18n'
Django:
djangobook.py3k.cn/2.0/chapter19/
1/14
2010-5-5
1. Python
2.
3. Django settings
1
Python
Python
ugettext() _ .
"Welcome to my site"
from django.utils.translation import ugettext as _
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)
from django.utils.translation import ugettext
def my_view(request):
output = ugettext("Welcome to my site.")
return HttpResponse(output)
def my_view(request):
words = ['Welcome', 'to', 'my', 'site.']
output = _(' '.join(words))
return HttpResponse(output)
def my_view(request):
sentence = 'Welcome to my site.'
output = _(sentence)
return HttpResponse(output)
Django
makemessages.py makemessages
djangobook.py3k.cn/2.0/chapter19/
2/14
2010-5-5
"Today is November 26." "Hoy es 26 de Noviembre."
%(day)s
%s or %d
django.utils.translation.gettext_noop()
django.utils.translation.gettext_lazy()
gettext_lazy()
help_text
from django.utils.translation import ugettext_lazy
class MyThing(models.Model):
name = models.CharField(help_text=ugettext_lazy('This is the help text'))
ugettext_lazy()
Django
Pythonunicode unicode
ugettext_lazy() ugettext_lazy()
unicode Python
# This is fine: putting a unicode proxy into a unicode string.
u"Hello %s" % ugettext_lazy("people")
# This will not work, since you cannot insert a unicode object
# into a bytestring (nor can you insert our unicode proxy there)
"Hello %s" % ugettext_lazy("people")
"hello"ugettext_lazy()
gettext_lazy _
from django.utils.translation import ugettext_lazy as _
class MyThing(models.Model):
name = models.CharField(help_text=_('This is the help text'))
Django
Metaverbose_naneverbose_name_plural
Djangoverbose_nameverbose_name_pluralmodel
djangobook.py3k.cn/2.0/chapter19/
3/14
2010-5-5
django.utils.translation.ungettext()
from django.utils.translation import ungettext
def hello_world(request, count):
page = ungettext('there is %(count)d object',
'there are %(count)d objects', count) % {
'count': count,
}
return HttpResponse(page)
ngettext count
DjangoPython
{% load i18n %}
{% trans %} ()
<title>{% trans "This is the title." %}</title>
<title>{% trans myvar %}</title>
noop
<title>{% trans "myvar" noop %}</title>
{% trans %} (
placeholders) {% blocktrans %}
{% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
blocktrans and
{% blocktrans with book|title as book_t and author|title as author_t %}
This is {{ book_t }} by {{ author_t }}
{% endblocktrans %}
djangobook.py3k.cn/2.0/chapter19/
4/14
2010-5-5
gettext ngettext
RequestContext
{{ LANGUAGES }}
LANGUAGE_CODE enusDjango
LANGUAGE_BIDI True
False
RequestContext3
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_current_language_bidi as LANGUAGE_BIDI %}
{% load i18n %}
hook _()
:
"yes,no""yes""no"
"yes,no"
"ja,nein" ()
ugettext_lazy()ungettext_lazy()
string_concat()
Python(''.join([...]) )
django.utils.translation.string_concat()
from django.utils.translation import string_concat
# ...
name = ugettext_lazy(u'John Lennon')
djangobook.py3k.cn/2.0/chapter19/
5/14
2010-5-5
instrument = ugettext_lazy(u'guitar')
result = string_concat([name, ': ', instrument])
allow_lazy()
Django(
django.utils )
django.utils.functional.allow_lazy()
Django
Django
Django DjangoDjango core
djangobook.py3k.cn/2.0/chapter19/
6/14
2010-5-5
.po
Django bin/makemessages.py
djangoadmin.py makemessages l de
de
pt_BR de_AT
Django
Django
django Subversion $PYTHONPATH
Django
locale/LANG/LC_MESSAGES de
locale/de/LC_MESSAGES/django.po
djangoadmin.py makemessages .html
extension e
djangoadmin.py makemessages l de e txt
eextension
djangoadmin.py makemessages l de e html,txt e xml
JavaScriptDjangonot e js
gettext?
gettext makemessages.py gettext
( conf/locale/en/LC_MESSAGES/django.po )
Windows
WindowsGNU gettext djangoadmin makemessages
Windowsgettext
.po .po
djangobook.py3k.cn/2.0/chapter19/
7/14
2010-5-5
msgid
msgstr
# msgid
msgstr msgid
djangoadmin.py makemessages a
gettext
djangoadmin.py compilemessages
.po .mo gettext
djangoadmin.py makemessagesdjangoadmin.py compilemessages
djangoadmin.py compilemessages
Django
Django
Django
LANGUAGE_CODEDjango
Django LANGUAGE_CODE
djangobook.py3k.cn/2.0/chapter19/
8/14
2010-5-5
MIDDLE_CLASSES
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
)
17
LocaleMiddleware :
session django_language
cookie
HTTP AcceptLanguage
Django
, LANGUAGE_CODE
ptbr
Django deat
Django de de
LANGUAGES
LANGUAGES
LANGUAGES = (
('de', _('German')),
('en', _('English')),
)
dech enus
LANGUAGES
django.utils.translation gettext() settings django.utils.translation
settings gettext()
gettext() settings
ugettext = lambda s: s
LANGUAGES = (
djangobook.py3k.cn/2.0/chapter19/
9/14
2010-5-5
('de', ugettext('German')),
('en', ugettext('English')),
makemessages.py
LANGUAGES ugettext()
LocaleMiddleware Django Django
Django
ID
.po
ID ID:
DATETIME_FORMAT DATE_FORMAT TIME_FORMAT
now
LocaleMiddlewarerequest.LANGUAGE_CODEHttpRequest
def hello_world(request):
if request.LANGUAGE_CODE == 'deat':
return HttpResponse("You prefer to read Austrian German.")
else:
return HttpResponse("You prefer to read another language.")
settings.LANGUAGE_CODE
request.LANGUAGE_CODE
Django
Django locale
Django locale
Django django/conf/locale
$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)
$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)
settings LOCALE_PATHS
<language>/LC_MESSAGES/django.(po|mo)
djangobook.py3k.cn/2.0/chapter19/
10/14
2010-5-5
$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)
LocaleMiddle Django
Django
makemessages
ID
makemessages
set_language
Django django.views.i18n.set_language
URLconf
(r'^i18n/', include('django.conf.urls.i18n')),
/i18n/setlang/
GET language session
session django_languagecookie(
LANGUAGE_COOKIE_NAME)
Django
Django POST
next DjangoHTML Referer
Referer Referer /
HTML
<form action="/i18n/setlang/" method="post">
<input name="next" type="hidden" value="/next/page/" />
<select name="language">
{% for lang in LANGUAGES %}
<option value="{{ lang.0 }}">{{ lang.1 }}</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
djangobook.py3k.cn/2.0/chapter19/
11/14
2010-5-5
</form>
JavaScript
JavaScript
JavaScript gettext
JavaScript .po .mo
JavaScript
Django JavaScriptJavaScript
gettext
javascript_catalog
javascript_catalog JavaScript
gettext info_dictURl
Django
js_info_dict = {
'packages': ('your.app.package',),
}
urlpatterns = patterns('',
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)
packages Python INSTALLED_APPS
locale
JavaScript
urlpatterns
urlpatterns = patterns('',
(r'^jsi18n/(?P<packages>\S+)/$', 'django.views.i18n.javascript_catalog'),
)
URL +
django.conf INSTALLED_APPS
JavaScript
JavaScript gettext
djangobook.py3k.cn/2.0/chapter19/
12/14
2010-5-5
document.write(gettext('this is to be translated'));
ngettext
var object_cnt = 1 // or 0, or 2, or 3, ...
s = ngettext('literal for the singular case',
'literal for the plural case', object_cnt);
Pythoninterpolate
objJavaScriptfmt
fmts = ngettext('There is %s object. Remaining: %s',
'There are %s objects. Remaining: %s', 11);
s = interpolate(fmts, [11, 20]);
// s is 'There are 11 objects. Remaining: 20'
JavaScript
Python ngettext
JavaScript
Djangodjango-admin.py makemessages
d djangojs
djangoadmin.py makemessages d djangojs l de
JavaScript Django
compilemessages.py
gettext
gettext Django
django djangojs
/usr/share/locale/ django Python
djangojs JavaScript
djangobook.py3k.cn/2.0/chapter19/
13/14
2010-5-5
Django xgettext Pythonxgettextmsgfmt
Windowsgettext
gettext
http://sourceforge.net/projects/gettextzip
gettextruntimeX.bin.woe32.zip
gettexttoolsX.bin.woe32.zip
libiconvX.bin.woe32.zip
3 C:\Program Files\gettextutils )
PathEdit
;C:\Program Files\gettextutils\bin
| | | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter19/
14/14
2010-5-5
About | Comment help | Contact us | Errata | Buy the print version on Amazon.com
| | | |
Internet
Web WebWeb
Django web
Django
web
Django
Web
HTTP
Web
HTTPcookies
SQL
SQL SQLweb GET /POST URL
SQL
SQL
emailemail
def user_contacts(request):
user = request.GET['username']
sql = "SELECT * FROM user_contacts WHERE username = '%s';" % username
# execute the SQL here...
djangobook.py3k.cn/2.0/chapter20/
1/8
2010-5-5
email
"' OR 'a'='a"
SELECT * FROM user_contacts WHERE username = '' OR 'a' = 'a';
SQL OR
"'; DELETE FROM user_contacts WHERE 'a' = 'a'"
SELECT * FROM user_contacts WHERE username = ''; DELETE FROM user_contacts WHERE 'a' = 'a';
SQL
DjangoAPI PostSQLMySQL
SQL
API
foo.get_list(bar__exact="' OR 1=1")
Django
SELECT * FROM foos WHERE bar = '\' OR 1=1'
DjangoAPI
extra() where ( C) SQL
API ()
from django.db import connection
def user_contacts(request):
user = request.GET['username']
sql = "SELECT * FROM user_contacts WHERE username = %s"
cursor = connection.cursor()
cursor.execute(sql, [user])
# ... do something with the results
execute SQLSQL%s
djangobook.py3k.cn/2.0/chapter20/
2/8
2010-5-5
(XSS)
Web (XSS)HTML
<script> HTML
XSScookie
Hello World
from django.http import HttpResponse
def say_hello(request):
name = request.GET.get('name', 'world')
return HttpResponse('<h1>Hello, %s!</h1>' % name)
GEThello.html
http://example.com/hello/?name=Jacob
<h1>Hello, Jacob!</h1>
http://example.com/hello/?name=<i>Jacob</i>
<h1>Hello, <i>Jacob</i>!</h1>
<i>HTML
XSS
MySpaceXSS
JavaScript
MySpace
MySpaceMySpace
MySpace
Django
djangobook.py3k.cn/2.0/chapter20/
3/8
2010-5-5
# views.py
from django.shortcuts import render_to_response
def say_hello(request):
name = request.GET.get('name', 'world')
return render_to_response('hello.html', {'name': name})
# hello.html
<h1>Hello, {{ name }}!</h1>
`` http://example.com/hello/name=Jacob``
<h1>Hello, <i>Jacob</i>!</h1>
Django Django
XSS
(CSRF)WebURL
Django 16
ID
cookie
cookie cookie
cookie cookie `
<../chapter14/>`__ cookies
cookies
Web IsLoggedIn=1 LoggedInAsUser=jacob cookie
cookie
cookies
ID
PHPURL http://example.com/?PHPSESSID=fa90197ca25f6ab40bb1374c510d7a32
ID
djangobook.py3k.cn/2.0/chapter20/
4/8
2010-5-5
Web
cookie
XSS
URLsession
Djangosession` <../chapter14/>`__ sessionURL
cookie sessionsession ID
Djangosession request.session session
cookiesession IDsession
session XSS
session
session
IDDjango
ID
ID
HTTPS
SSL SESSION_COOKIE_SECURE True DjangoHTTPS
cookie
SQLWeb
Web
from
"hello\ncc:spamvictim@example.com" "\n"
To: hardcoded@example.com
Subject: hello
cc: spamvictim@example.com
djangobook.py3k.cn/2.0/chapter20/
5/8
2010-5-5
SQL
SQL
Django django.core.mail
django.core.mail.send_mail
DjangoBadHeaderError
Django
django.core.mail SateMIMEText Django
Web
/
def dump_file(request):
filename = request.GET["filename"]
filename = os.path.join(BASE_PATH, filename)
content = open(filename).read()
# ...
BASE_PATH os.path.join
.. BASE_PATH
../../../../../etc/passwd
URL
Ruby on Rails 2006Rails http://example.com/person/poke/1 URL
URL
Django django.views.static
import os
import posixpath
# ...
path = posixpath.normpath(urllib.unquote(path))
newpath = ''
djangobook.py3k.cn/2.0/chapter20/
6/8
2010-5-5
Django static.serve
URLconfDjango
URLDjangoURLconf
Djangodebug
Django
Python
debug
12Django`` DEBUG``
`` False``
Apachemod_pythonApache PythonDebug Off
Django
Web
Web
Web
Djang.
Djangogoogle
djangobook.py3k.cn/2.0/chapter20/
7/8
2010-5-5
| | | |
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This w ork is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
djangobook.py3k.cn/2.0/chapter20/
8/8