Professional Documents
Culture Documents
Django: A High-Level Python Web Framework That Encourages Rapid Development and Clean, Pragmatic Design
Django: A High-Level Python Web Framework That Encourages Rapid Development and Clean, Pragmatic Design
Django 入門簡介 ( 二 )
MVC
Django File Structures
Development Environment/Web Server
HelloWorld
Settings.py
Admin Interface (admin.py)
Very Basic URLConf Usage
Very Basic Template Usage
Very Basic Model Usage
HTTP
Request
mysite/
__init__.py
manage.py
settings.py
urls.py
Follow me #2: Create application
cd mysite
python manage.py startapp books
mysite/books/
__init__.py
models.py
views.py
Follow me #3-1: Write model
mysite/books/models.py
from django.db import models #auto generate
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()
Follow me #3-2: Write model
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()
Explain Model
Fields
CharField
EmailField
IPAddressField
DateTimeField
.... lots of fields to define
http://www.djangobook.com/en/1.0/appendixB/
Follow me #4: Create Database
notepad++ settings.py
DATABASE_ENGINE : sqlite3
DATABASE_NAME : books.db
INSTALLED_APPS = 'mysite.books'
python manage.py syncdb
# also create a superuser
Review: What Did We Do?
>>> p2 = Publisher(name="O'Reilly",
address='10 Fawcett St.',
... city='Cambridge', state_province='MA',
country='U.S.A.',
... website='http://www.oreilly.com/')
>>> p2.save()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher:
Publisher object>]
2 Create Methods
p1 = Publisher(...)
# At this point, p1 is not saved to the database yet!
p1.save()
=========================================
>>> p1 = Publisher.objects.create(name='Apress',
... address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA',
country='U.S.A.',
... website='http://www.apress.com/')
__unicode__()
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
....
def __unicode__(self):
return self.name
Add __unicode__ to models
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)
Add __unicode__ to models
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
__unicode__() effect
Was:
>>> publisher_list
[<Publisher: Publisher object>, <Publisher:
Publisher object>]
Now:
>>> from books.models import Publisher
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Apress>, <Publisher: O'Reilly>]
Advanced: lambda, anonymous
functions
Publisher.__unicode__ = lambda self: self.name
Author.__unicode__ = lambda self: u'%s %s' %
(self.first_name, self.last_name)
Book.__unicode__ = lambda self: self.title
You could just define a Named function and
bind it in the django shell without use lambda.
>>> def bookunicode(self):
>>> return self.title
>>> Book.__unicode__ = bookunicode
Create More Objects (INSERT)
>>> p = Publisher(name='Apress',
... address='2855 Telegraph Ave.',
... city='Berkeley',
... state_province='CA',
... country='U.S.A.',
... website='http://www.apress.com/')
>>> p.save()
SQL
>>> p.id
52
>>> p.name = 'Apress Publishing'
>>> p.save()
SQL
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
SQL
Publisher.objects.all()
Manager
Advanced: Manager
>>> Book.objects.title_count('django')
4
>>> Book.objects.title_count('python')
18
How to manually use SQL in
models?
Standard Python DBAPI
>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute("""
... SELECT DISTINCT first_name
... FROM people_person
... WHERE last_name = %s""", ['Lennon'])
>>> row = cursor.fetchone()
>>> print row
['John']
Advanced Manager Usage:
Custom SQL in Models
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
FROM people_person
WHERE last_name = %s""", [last_name])
return [row[0] for row in cursor.fetchone()]
Custom SQL define in models
class Person(models.Model):
first_name =
models.CharField(max_length=50)
last_name =
models.CharField(max_length=50)
objects = PersonManager()
SQL? Didn't see it now.
>>> Person.objects.first_names('Lennon')
['John', 'Cynthia']
Filtering Data
>>> Publisher.objects.filter(name='Apress')
[<Publisher: Apress>]
SQL
>>> Publisher.objects.filter(country="U.S.A.",
state_province="CA")
[<Publisher: Apress>]
SQL
>>>
Publisher.objects.filter(name__contains="pres
s")
[<Publisher: Apress>]
SQL
>>> Entry.objects.filter(headline__istartswith='will')
>>> Entry.objects.filter(headline__endswith='cats')
>>> Entry.objects.filter(headline__iendswith='cats')
>>> start_date = datetime.date(2005, 1, 1)
>>> end_date = datetime.date(2005, 3, 31)
>>>
Entry.objects.filter(pub_date__range=(start_date,
end_date))
More Field Lookups
>>> Publisher.objects.get(name="Penguin")
Traceback (most recent call last):
...
DoesNotExist: Publisher matching query does
not exist.
Handle Exception
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."
Ordering Data
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]
>>> Publisher.objects.order_by("address")
[<Publisher: O'Reilly>, <Publisher: Apress>]
>>>
Publisher.objects.order_by("state_province")
[<Publisher: Apress>, <Publisher: O'Reilly>]
Ordering Data
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()
class Meta:
ordering = ['name']
Chaining Lookups
>>>
Publisher.objects.filter(country="U.S.A.").ord
er_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
SQL
>>> Publisher.objects.order_by('name')[0]
<Publisher: Apress>
SQL:
SELECT id, name, address, city, state_province,
country, website
FROM books_publisher
ORDER BY name
LIMIT 1;
Slicing Data
>>> Publisher.objects.order_by('name')[0:2]
Publisher.objects.order_by('-name')[0]
Tips: SQL optimize Tricks:
update()
update()
Update Objects using save()
>>> p = Publisher.objects.get(name='Apress')
>>> p.name = 'Apress Publishing'
>>> p.save()
Problem: updates all columns in a row.
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',
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 52;
Update Objects Idioms
update()
>>>
Publisher.objects.filter(id=52).update(name='
Apress Publishing')
SQL
UPDATE books_publisher
SET name = 'Apress Publishing'
WHERE id = 52;
Update QuerySet
>>> p = Publisher.objects.get(name="O'Reilly")
>>> p.delete()
>>> Publisher.objects.all()
[<Publisher: Apress Publishing>]
>>>
Publisher.objects.filter(country='USA').delete()
>>> Publisher.objects.all().delete()
>>> Publisher.objects.all()
[]
Deleting Objects
Delete All Objects:
>>> Publisher.objects.all().delete()
Delete Subset Objects:
>>>
Publisher.objects.filter(country='USA').delete()
Remember use all()
>>> Publisher.objects.delete()
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Manager' object has no attribute
'delete'
Dynamic Web Site
Template
Remember Helloworld?
def hello(request):
return HttpResponse("Hello world")
What do you need for a django
program?
You Just need these things in Django's view:
Define a function
IN: Request
OUT: Response
No template Need.
No models (database) Need.
Just view and urlconf are enough for web
scripts.
views.py
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now
%s.</body></html>" % now
return HttpResponse(html)
What's Wrong?
{{ variable }}
Use a dot (.) to access attributes of a variable.
* Dictionary lookup
* Attribute lookup
* Method call
* List-index lookup
http://docs.djangoproject.com/en/dev/topics/templates/#using-the-built-in-reference
Example:
{{ section.title }}
Variables
{% extends "base_generic.html" %}
{% block title %}{{ section.title }}{% endblock %}
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2> <a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a> </h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
Filters
{{ value|default:"nothing" }}
{{ value|length }}
{{ value|striptags }}
If value is "<b>Joel</b> <button>is</button> a
<span>slug</span>", the output will be "Joel is
a slug".
escape filter
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
if else
{% if athlete_list %}
Number of athletes: {{ athlete_list|length }}
{% else %}
No athletes.
{% endif %}
ifequal and ifnotequal
comment syntax: {# #}
{# greeting #}hello
Only render 'hello'
A comment can contain any template code
{# {% if foo %}bar{% else %} #}
only be used for single-line comments
Multiple lines:
{% comment %} and {% endcomment %}
Template inheritance
{% block content %}
...
{% endblock content %}
Base.html
<head><link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{% endblock %}</title></head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
Child.html
{% extends "base.html" %}
def hello(request):
return HttpResponse("Hello world")
HttpRequest
views.py
from django.shortcuts import
render_to_response
def search_form(request):
return
render_to_response('search_form.html')
HTML
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
urlpatterns = patterns('',
# ...
(r'^search-form/$', 'books.views.search_form'),
# ...
)
Add Search function
# urls.py
urlpatterns = patterns('',
# ...
(r'^search-form/$', 'books.views.search_form'),
(r'^search/$', 'books.views.search'),
# ...
)
views.py (1 -- Easy)
# 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)
views.py (2-1 Use DataBase)
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 HttpResponse('Please submit a search
term.')
search_results.html
<p>You searched for: <strong>{{ query }}</strong></p>
{% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
<ul>
{% for book in books %}
<li>{{ book.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>No books matched your search criteria.</p>
{% endif %}
Thanks
To Be Continued!
辛苦了 ! 請繼續參加 Django 入門簡介 ( 三 )