SlideShare una empresa de Scribd logo
1 de 99
Descargar para leer sin conexión
Advanced Models
「The Django Book」 Chapter 10
Spin	 Lai
July	 23,	 2013
2013年7月24日星期三
賴司平	 (Spin)
	 資拓宏宇	 	 氣象科技事業處
	 PHP、Javascript、Python
About me
2013年7月24日星期三
Related	 objects
	 Update	 database	 schema	 
	 Model	 methods
	 Managers
	 Execute	 raw	 SQL	 queries
	 More	 about	 Managers
Today’s topics
2013年7月24日星期三
Related objects
2013年7月24日星期三
Recalling the
Chapter 5 ...
2013年7月24日星期三
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
CharField
CharField
URLField
Book
id
title
authors
publisher
publication_date
AutoField
CharField
ManyToManyField
ForeignKey
DateField
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
N:1N:M
2013年7月24日星期三
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
2013年7月24日星期三
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)
2013年7月24日星期三
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
2013年7月24日星期三
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
2013年7月24日星期三
Foreign Key Value
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
CharField
CharField
URLField
Book
id
title
authors
publisher
AutoField
CharField
ManyToManyField
ForeignKey
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
<Publisher: Apress Publishing>
2013年7月24日星期三
Foreign Key Value
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
CharField
CharField
URLField
Book
id
title
authors
publisher
AutoField
CharField
ManyToManyField
ForeignKey
>>> p = Publisher.objects.get(name='Apress
Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into
Python>, ...]
>>> p.book_set.filter(name__icontains='django')
[<Book: The Django Book>, <Book: Pro Django>]
2013年7月24日星期三
Foreign Key Value
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
CharField
CharField
URLField
Book
id
title
authors
publisher
AutoField
CharField
ManyToManyField
ForeignKey
>>> p = Publisher.objects.get(name='Apress
Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into
Python>, ...]
>>> p.book_set.filter(name__icontains='django')
[<Book: The Django Book>, <Book: Pro Django>]
2013年7月24日星期三
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
2013年7月24日星期三
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
2013年7月24日星期三
Many-to-Many Values
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
Book
id
title
authors
publisher
AutoField
CharField
ManyToManyField
ForeignKey
>>> b = Book.objects.get(id=50)
>>> b.authors.all()
[<Author: Adrian Holovaty>, <Author:
Jacob Kaplan-Moss>]
>>> b.authors.filter
(first_name='Adrian')
[<Author: Adrian Holovaty>]
>>> b.authors.filter
(first_name='Adam')
[]
2013年7月24日星期三
Many-to-Many Values
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
Book
id
title
authors
publisher
AutoField
CharField
ManyToManyField
ForeignKey
>>> a = Author.objects.get(first_name='Adrian',
last_name='Holovaty')
>>> a.book_set.all()
[<Book: The Django Book>, <Book: Adrian's Other
Book>]'
2013年7月24日星期三
Many-to-Many Values
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
Book
id
title
authors
publisher
AutoField
CharField
ManyToManyField
ForeignKey
>>> a = Author.objects.get(first_name='Adrian',
last_name='Holovaty')
>>> a.book_set.all()
[<Book: The Django Book>, <Book: Adrian's Other
Book>]'
2013年7月24日星期三
Update database
schema
2013年7月24日星期三
First of all
2013年7月24日星期三
Does not care extra DB table columns
Does not care extra DB tables
Complains if model contains fields that
has not yet been created in the DB table
Django
2013年7月24日星期三
`syncdb` only create
tables for models which
have not yet been
installed.
2013年7月24日星期三
Add	 model	 fields
	 Remove	 model	 fields	 
	 Remove	 models
Update database schema
2013年7月24日星期三
Add model fields
2013年7月24日星期三
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify new fields was added properly
In development environments ...
2013年7月24日星期三
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify new fields was added properly
In development environments ...
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
2013年7月24日星期三
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify new fields was added properly
In development environments ...
CREATE TABLE "books_book" (
"id" serial NOT NULL PRIMARY KEY,
"title" varchar(100) NOT NULL,
"publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"),
"publication_date" date NOT NULL,
"num_pages" integer NULL
);
$ python manage.py sqlall books
2013年7月24日星期三
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify new fields was added properly
In development environments ...
ALTER TABLE books_book ADD COLUMN num_pages integer;
2013年7月24日星期三
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify new fields was added properly
In development environments ...
>>> from mysite.books.models import Book
>>> Book.objects.all()[:5]
2013年7月24日星期三
Add model fields
Add new columns to the DB table
Add fields to the model
Restart the web server
In production environments ...
2013年7月24日星期三
Remove model fields
2013年7月24日星期三
Add model fields
Remove fields from the model
Restart the web server
Remove columns from the DB table
Remove Normal fields ...
2013年7月24日星期三
Add model fields
Remove fields from the model
Restart the web server
Remove columns from the DB table
Remove Normal fields ...
ALTER TABLE books_book DROP COLUMN num_pages;
2013年7月24日星期三
Add model fields
Remove Many-to-Many fields from the model
Restart the web server
Remove Many-to-Many table from the DB
Remove Many-to-Many fields ...
2013年7月24日星期三
Add model fields
Remove Many-to-Many fields from the model
Restart the web server
Remove Many-to-Many table from the DB
Remove Many-to-Many fields ...
DROP TABLE books_book_authors;
2013年7月24日星期三
Remove models
2013年7月24日星期三
Remove model from the models.py
Restart the web server
Remove dependent tables from the DB
Remove the target table from the DB
Remove models
2013年7月24日星期三
Remove model from the `models.py`
Restart the web server
Remove dependent tables from the DB
Remove the target table from the DB
Remove models
DROP TABLE books_book;
2013年7月24日星期三
Model methods
2013年7月24日星期三
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 baby-boomer 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):
return "Pre-boomer"
return "Post-boomer"
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)
2013年7月24日星期三
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 baby-boomer 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):
return "Pre-boomer"
return "Post-boomer"
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)
2013年7月24日星期三
Model methods
>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.birth_date
datetime.date(1961, 8, 4)
>>> p.baby_boomer_status()
'Baby boomer'
>>> p.is_midwestern()
True
2013年7月24日星期三
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 baby-boomer 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):
return "Pre-boomer"
return "Post-boomer"
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)
2013年7月24日星期三
Property methods
>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.full_name # Note this isn't a method
u'Barack Obama'
2013年7月24日星期三
Managers
2013年7月24日星期三
What is Manager?
2013年7月24日星期三
Manager
Book.objects.all()
2013年7月24日星期三
Manager
Book.objects.all()
2013年7月24日星期三
Manager
“ The interface through which database
query operations are provided to
Django models. ”
2013年7月24日星期三
Why do we need a
custom Manager?
2013年7月24日星期三
Add	 extra	 Manager	 methods
	 Modify	 initial	 Manager	 QuerySets	 
Custom Mangers
2013年7月24日星期三
Add extra Manager
methods
2013年7月24日星期三
Add extra Manager methods
# Get the number of books that have a title ‘Django’
>>> Book.objects.filter(title__icontains='Django')
# Get the number of books that have a title ‘Python’
>>> Book.objects.filter(title__icontains='Python')
# Get the number of books that have a title ‘xxx’
....
# Get the number of books that have a title ‘yyy’
....
.....
.......
2013年7月24日星期三
Add extra Manager methods
# takes a keyword and returns the number of books
>>> Book.objects.title_count('django')
>>> Book.objects.title_count('python')
2013年7月24日星期三
# 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)
objects = BookManager()
def __unicode__(self):
return self.title
2013年7月24日星期三
# 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)
objects = BookManager()
def __unicode__(self):
return self.title
2013年7月24日星期三
Modify initial Manager
QuerySets
2013年7月24日星期三
Modify initial Manager QuerySets
Default Manager return all the records
Override Manager’s base QuerySets
2013年7月24日星期三
Modify initial Manager QuerySets
Default Manager return all the records
Override Manager’s base QuerySets
# returns all books in the book database
>>> Book.objects.all()
2013年7月24日星期三
Modify initial Manager QuerySets
Default Manager return all the records
Override Manager’s base QuerySets
By overriding the Manager.get_query_set()
2013年7月24日星期三
Modify initial Manager QuerySets
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 Dahl-specific manager.
2013年7月24日星期三
Modify initial Manager QuerySets
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 Dahl-specific manager.
2013年7月24日星期三
Modify initial Manager QuerySets
>>> Book.dahl_objects.all()
>>> Book.dahl_objects.filter(title='Matilda')
>>> Book.dahl_objects.count()
2013年7月24日星期三
Another example
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()
2013年7月24日星期三
Another example
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()
2013年7月24日星期三
Modify initial Manager QuerySets
>>> Person.men.all()
>>> Person.women.all()
>>> Person.people.all()
2013年7月24日星期三
Execute raw SQL
queries
2013年7月24日星期三
Django DB objects
2013年7月24日星期三
connection object
cursor object
cursor.execute()
cursor.fetchone() / cursor.fetchall()
Implement the Python DB-API (PEP-0249)
Django DB objects
2013年7月24日星期三
Execute raw SQL queries
>>> 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']
2013年7月24日星期三
Execute raw SQL queries
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()]
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
objects = PersonManager()
2013年7月24日星期三
Execute raw SQL queries
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()]
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
objects = PersonManager()
2013年7月24日星期三
Execute raw SQL queries
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()]
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
objects = PersonManager()
2013年7月24日星期三
Execute raw SQL queries
>>> Person.objects.first_names('Lennon')
['John', 'Cynthia']
2013年7月24日星期三
More about
Managers
2013年7月24日星期三
As mentioned previously...
2013年7月24日星期三
Business logic encapsulation
Add custom Managers
Override default Manager with custom
methods
2013年7月24日星期三
Add custom Managers
class IncompleteTodoManager(models.Manager):
def get_query_set(self):
return super(TodoManager, self).get_query_set().filter(is_done=False)
class HighPriorityTodoManager(models.Manager):
def get_query_set(self):
return super(TodoManager, self).get_query_set().filter(priority=1)
class Todo(models.Model):
content = models.CharField(max_length=100)
# other fields go here..
objects = models.Manager() # the default manager
# attach our custom managers:
incomplete = models.IncompleteTodoManager()
high_priority = models.HighPriorityTodoManager()
2013年7月24日星期三
Add custom Managers
class IncompleteTodoManager(models.Manager):
def get_query_set(self):
return super(TodoManager, self).get_query_set().filter(is_done=False)
class HighPriorityTodoManager(models.Manager):
def get_query_set(self):
return super(TodoManager, self).get_query_set().filter(priority=1)
class Todo(models.Model):
content = models.CharField(max_length=100)
# other fields go here..
objects = models.Manager() # the default manager
# attach our custom managers:
incomplete = models.IncompleteTodoManager()
high_priority = models.HighPriorityTodoManager()
2013年7月24日星期三
Add custom Managers
>>> Todo.incomplete.all()
>>> Todo.high_priority.all()
2013年7月24日星期三
But
2013年7月24日星期三
Drawbacks
Verbose Managers
Cluttered model namespace
Not chainable
2013年7月24日星期三
Custom Manager methods
2013年7月24日星期三
Custom Manager methods
class TodoManager(models.Manager):
def incomplete(self):
return self.filter(is_done=False)
def high_priority(self):
return self.filter(priority=1)
class Todo(models.Model):
content = models.CharField(max_length=100)
# other fields go here..
objects = TodoManager()
2013年7月24日星期三
Custom Manager methods
>>> Todo.objects.incomplete()
>>> Todo.objects.high_priority()
2013年7月24日星期三
But
2013年7月24日星期三
Drawbacks
Not chainable between custom methods.
# It didn’t work !
>>> Todo.objects.incomplete().high_priority()
2013年7月24日星期三
Custom QuerySets
2013年7月24日星期三
Custom QuerySets
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def high_priority(self):
return self.filter(priority=1)
class TodoManager(models.Manager):
def get_query_set(self):
return TodoQuerySet(self.model, using=self._db)
class Todo(models.Model):
content = models.CharField(max_length=100)
# other fields go here..
objects = TodoManager()
2013年7月24日星期三
Custom QuerySets
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def high_priority(self):
return self.filter(priority=1)
class TodoManager(models.Manager):
def get_query_set(self):
return TodoQuerySet(self.model, using=self._db)
class Todo(models.Model):
content = models.CharField(max_length=100)
# other fields go here..
objects = TodoManager()
2013年7月24日星期三
Custom QuerySets
>>> Todo.objects.get_query_set().incomplete()
>>> Todo.objects.get_query_set().high_priority()
>>> # (or)
>>> Todo.objects.all().incomplete()
>>> Todo.objects.all().high_priority()
>>> # Chainable !!!
>>> Todo.objects.all().incomplete().high_priority()
2013年7月24日星期三
But
2013年7月24日星期三
Custom QuerySets
>>> Todo.objects.get_query_set().incomplete()
>>> Todo.objects.get_query_set().high_priority()
>>> # (or)
>>> Todo.objects.all().incomplete()
>>> Todo.objects.all().high_priority()
>>> # Chainable !!!
>>> Todo.objects.all().incomplete().high_priority()
2013年7月24日星期三
Custom QuerySets
>>> Todo.objects.get_query_set().incomplete()
>>> Todo.objects.get_query_set().high_priority()
>>> # (or)
>>> Todo.objects.all().incomplete()
>>> Todo.objects.all().high_priority()
>>> # Chainable !!!
>>> Todo.objects.all().incomplete().high_priority()
Ug==Ugly !!
2013年7月24日星期三
Proxy everything !!
2013年7月24日星期三
Proxy everything !!
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def high_priority(self):
return self.filter(priority=1)
class TodoManager(models.Manager):
def get_query_set(self):
return TodoQuerySet(self.model, using=self._db)
def incomplete(self):
return self.get_query_set().incomplete()
def high_priority(self):
return self.get_query_set().high_priority()
2013年7月24日星期三
Proxy everything !!
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def high_priority(self):
return self.filter(priority=1)
class TodoManager(models.Manager):
def get_query_set(self):
return TodoQuerySet(self.model, using=self._db)
def incomplete(self):
return self.get_query_set().incomplete()
def high_priority(self):
return self.get_query_set().high_priority()
2013年7月24日星期三
Proxy everything !!
>>> Todo.objects.incomplete().high_priority() # Perfect !!
2013年7月24日星期三
Thank you
2013年7月24日星期三

Más contenido relacionado

Similar a The django book - Chap10 : Advanced Models

Meet Django - Django Webframework in Python
Meet Django - Django Webframework in PythonMeet Django - Django Webframework in Python
Meet Django - Django Webframework in PythonBas Koopmans
 
03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slots03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slotsmha4
 
03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slots03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slotsmha4
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design PatternsLilia Sfaxi
 
Retail referencearchitecture productcatalog
Retail referencearchitecture productcatalogRetail referencearchitecture productcatalog
Retail referencearchitecture productcatalogMongoDB
 
06 InheritanceAndPolymorphism.ppt
06 InheritanceAndPolymorphism.ppt06 InheritanceAndPolymorphism.ppt
06 InheritanceAndPolymorphism.pptParikhitGhosh1
 
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE
w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE tidwellerin392
 
Views Mini-Course, Part I: An Introduction to Views
Views Mini-Course, Part I: An Introduction to ViewsViews Mini-Course, Part I: An Introduction to Views
Views Mini-Course, Part I: An Introduction to ViewsAcquia
 
Applying sys ml_with_magicdraw
Applying sys ml_with_magicdrawApplying sys ml_with_magicdraw
Applying sys ml_with_magicdrawelheshk
 
Views for hackers v1.3
Views for hackers v1.3Views for hackers v1.3
Views for hackers v1.3Karim Ratib
 
Is2215 lecture2 student(2)
Is2215 lecture2 student(2)Is2215 lecture2 student(2)
Is2215 lecture2 student(2)dannygriff1
 
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPPresentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPOdoo
 
Simplifying Model Management with MLflow
Simplifying Model Management with MLflowSimplifying Model Management with MLflow
Simplifying Model Management with MLflowDatabricks
 
Django and working with large database tables
Django and working with large database tablesDjango and working with large database tables
Django and working with large database tablesIlian Iliev
 
Introduction to R Programming
Introduction to R ProgrammingIntroduction to R Programming
Introduction to R Programmingizahn
 

Similar a The django book - Chap10 : Advanced Models (20)

Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
Meet Django - Django Webframework in Python
Meet Django - Django Webframework in PythonMeet Django - Django Webframework in Python
Meet Django - Django Webframework in Python
 
03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slots03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slots
 
03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slots03 object-classes-pbl-4-slots
03 object-classes-pbl-4-slots
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Retail referencearchitecture productcatalog
Retail referencearchitecture productcatalogRetail referencearchitecture productcatalog
Retail referencearchitecture productcatalog
 
06 InheritanceAndPolymorphism.ppt
06 InheritanceAndPolymorphism.ppt06 InheritanceAndPolymorphism.ppt
06 InheritanceAndPolymorphism.ppt
 
Angular betabeers
Angular betabeersAngular betabeers
Angular betabeers
 
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE
w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE
 
Views Mini-Course, Part I: An Introduction to Views
Views Mini-Course, Part I: An Introduction to ViewsViews Mini-Course, Part I: An Introduction to Views
Views Mini-Course, Part I: An Introduction to Views
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Jscript part2
Jscript part2Jscript part2
Jscript part2
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Applying sys ml_with_magicdraw
Applying sys ml_with_magicdrawApplying sys ml_with_magicdraw
Applying sys ml_with_magicdraw
 
Views for hackers v1.3
Views for hackers v1.3Views for hackers v1.3
Views for hackers v1.3
 
Is2215 lecture2 student(2)
Is2215 lecture2 student(2)Is2215 lecture2 student(2)
Is2215 lecture2 student(2)
 
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPPresentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERP
 
Simplifying Model Management with MLflow
Simplifying Model Management with MLflowSimplifying Model Management with MLflow
Simplifying Model Management with MLflow
 
Django and working with large database tables
Django and working with large database tablesDjango and working with large database tables
Django and working with large database tables
 
Introduction to R Programming
Introduction to R ProgrammingIntroduction to R Programming
Introduction to R Programming
 

Más de Spin Lai

Django User Management & Social Authentication
Django User Management & Social AuthenticationDjango User Management & Social Authentication
Django User Management & Social AuthenticationSpin Lai
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginnersSpin Lai
 
Bdd for legacy system
Bdd for legacy systemBdd for legacy system
Bdd for legacy systemSpin Lai
 
Two scoops of Django - Security Best Practices
Two scoops of Django - Security Best PracticesTwo scoops of Django - Security Best Practices
Two scoops of Django - Security Best PracticesSpin Lai
 
Speed up your web development
Speed up your web developmentSpeed up your web development
Speed up your web developmentSpin Lai
 
Hitcon2013 overview
Hitcon2013 overviewHitcon2013 overview
Hitcon2013 overviewSpin Lai
 

Más de Spin Lai (6)

Django User Management & Social Authentication
Django User Management & Social AuthenticationDjango User Management & Social Authentication
Django User Management & Social Authentication
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginners
 
Bdd for legacy system
Bdd for legacy systemBdd for legacy system
Bdd for legacy system
 
Two scoops of Django - Security Best Practices
Two scoops of Django - Security Best PracticesTwo scoops of Django - Security Best Practices
Two scoops of Django - Security Best Practices
 
Speed up your web development
Speed up your web developmentSpeed up your web development
Speed up your web development
 
Hitcon2013 overview
Hitcon2013 overviewHitcon2013 overview
Hitcon2013 overview
 

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Último (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

The django book - Chap10 : Advanced Models

  • 1. Advanced Models 「The Django Book」 Chapter 10 Spin Lai July 23, 2013 2013年7月24日星期三
  • 2. 賴司平 (Spin) 資拓宏宇 氣象科技事業處 PHP、Javascript、Python About me 2013年7月24日星期三
  • 3. Related objects Update database schema Model methods Managers Execute raw SQL queries More about Managers Today’s topics 2013年7月24日星期三
  • 5. Recalling the Chapter 5 ... 2013年7月24日星期三
  • 7. 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 2013年7月24日星期三
  • 8. 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) 2013年7月24日星期三
  • 9. 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 2013年7月24日星期三
  • 10. 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 2013年7月24日星期三
  • 11. Foreign Key Value Publisher id name address city state_province country website AutoField CharField CharField CharField CharField CharField URLField Book id title authors publisher AutoField CharField ManyToManyField ForeignKey >>> b = Book.objects.get(id=50) >>> b.publisher <Publisher: Apress Publishing> >>> b.publisher.website u'http://www.apress.com/' <Publisher: Apress Publishing> 2013年7月24日星期三
  • 12. Foreign Key Value Publisher id name address city state_province country website AutoField CharField CharField CharField CharField CharField URLField Book id title authors publisher AutoField CharField ManyToManyField ForeignKey >>> p = Publisher.objects.get(name='Apress Publishing') >>> p.book_set.all() [<Book: The Django Book>, <Book: Dive Into Python>, ...] >>> p.book_set.filter(name__icontains='django') [<Book: The Django Book>, <Book: Pro Django>] 2013年7月24日星期三
  • 13. Foreign Key Value Publisher id name address city state_province country website AutoField CharField CharField CharField CharField CharField URLField Book id title authors publisher AutoField CharField ManyToManyField ForeignKey >>> p = Publisher.objects.get(name='Apress Publishing') >>> p.book_set.all() [<Book: The Django Book>, <Book: Dive Into Python>, ...] >>> p.book_set.filter(name__icontains='django') [<Book: The Django Book>, <Book: Pro Django>] 2013年7月24日星期三
  • 14. 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 2013年7月24日星期三
  • 15. 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 2013年7月24日星期三
  • 16. Many-to-Many Values Author id first_name last_name email AutoField CharField CharField EmailField Book id title authors publisher AutoField CharField ManyToManyField ForeignKey >>> b = Book.objects.get(id=50) >>> b.authors.all() [<Author: Adrian Holovaty>, <Author: Jacob Kaplan-Moss>] >>> b.authors.filter (first_name='Adrian') [<Author: Adrian Holovaty>] >>> b.authors.filter (first_name='Adam') [] 2013年7月24日星期三
  • 17. Many-to-Many Values Author id first_name last_name email AutoField CharField CharField EmailField Book id title authors publisher AutoField CharField ManyToManyField ForeignKey >>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty') >>> a.book_set.all() [<Book: The Django Book>, <Book: Adrian's Other Book>]' 2013年7月24日星期三
  • 18. Many-to-Many Values Author id first_name last_name email AutoField CharField CharField EmailField Book id title authors publisher AutoField CharField ManyToManyField ForeignKey >>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty') >>> a.book_set.all() [<Book: The Django Book>, <Book: Adrian's Other Book>]' 2013年7月24日星期三
  • 21. Does not care extra DB table columns Does not care extra DB tables Complains if model contains fields that has not yet been created in the DB table Django 2013年7月24日星期三
  • 22. `syncdb` only create tables for models which have not yet been installed. 2013年7月24日星期三
  • 23. Add model fields Remove model fields Remove models Update database schema 2013年7月24日星期三
  • 25. Add model fields Add fields to the model Check the column definitions for new fields Add new columns to the DB table Verify new fields was added properly In development environments ... 2013年7月24日星期三
  • 26. Add model fields Add fields to the model Check the column definitions for new fields Add new columns to the DB table Verify new fields was added properly In development environments ... 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 2013年7月24日星期三
  • 27. Add model fields Add fields to the model Check the column definitions for new fields Add new columns to the DB table Verify new fields was added properly In development environments ... CREATE TABLE "books_book" ( "id" serial NOT NULL PRIMARY KEY, "title" varchar(100) NOT NULL, "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"), "publication_date" date NOT NULL, "num_pages" integer NULL ); $ python manage.py sqlall books 2013年7月24日星期三
  • 28. Add model fields Add fields to the model Check the column definitions for new fields Add new columns to the DB table Verify new fields was added properly In development environments ... ALTER TABLE books_book ADD COLUMN num_pages integer; 2013年7月24日星期三
  • 29. Add model fields Add fields to the model Check the column definitions for new fields Add new columns to the DB table Verify new fields was added properly In development environments ... >>> from mysite.books.models import Book >>> Book.objects.all()[:5] 2013年7月24日星期三
  • 30. Add model fields Add new columns to the DB table Add fields to the model Restart the web server In production environments ... 2013年7月24日星期三
  • 32. Add model fields Remove fields from the model Restart the web server Remove columns from the DB table Remove Normal fields ... 2013年7月24日星期三
  • 33. Add model fields Remove fields from the model Restart the web server Remove columns from the DB table Remove Normal fields ... ALTER TABLE books_book DROP COLUMN num_pages; 2013年7月24日星期三
  • 34. Add model fields Remove Many-to-Many fields from the model Restart the web server Remove Many-to-Many table from the DB Remove Many-to-Many fields ... 2013年7月24日星期三
  • 35. Add model fields Remove Many-to-Many fields from the model Restart the web server Remove Many-to-Many table from the DB Remove Many-to-Many fields ... DROP TABLE books_book_authors; 2013年7月24日星期三
  • 37. Remove model from the models.py Restart the web server Remove dependent tables from the DB Remove the target table from the DB Remove models 2013年7月24日星期三
  • 38. Remove model from the `models.py` Restart the web server Remove dependent tables from the DB Remove the target table from the DB Remove models DROP TABLE books_book; 2013年7月24日星期三
  • 40. 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 baby-boomer 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): return "Pre-boomer" return "Post-boomer" 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) 2013年7月24日星期三
  • 41. 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 baby-boomer 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): return "Pre-boomer" return "Post-boomer" 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) 2013年7月24日星期三
  • 42. Model methods >>> p = Person.objects.get(first_name='Barack', last_name='Obama') >>> p.birth_date datetime.date(1961, 8, 4) >>> p.baby_boomer_status() 'Baby boomer' >>> p.is_midwestern() True 2013年7月24日星期三
  • 43. 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 baby-boomer 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): return "Pre-boomer" return "Post-boomer" 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) 2013年7月24日星期三
  • 44. Property methods >>> p = Person.objects.get(first_name='Barack', last_name='Obama') >>> p.full_name # Note this isn't a method u'Barack Obama' 2013年7月24日星期三
  • 49. Manager “ The interface through which database query operations are provided to Django models. ” 2013年7月24日星期三
  • 50. Why do we need a custom Manager? 2013年7月24日星期三
  • 51. Add extra Manager methods Modify initial Manager QuerySets Custom Mangers 2013年7月24日星期三
  • 53. Add extra Manager methods # Get the number of books that have a title ‘Django’ >>> Book.objects.filter(title__icontains='Django') # Get the number of books that have a title ‘Python’ >>> Book.objects.filter(title__icontains='Python') # Get the number of books that have a title ‘xxx’ .... # Get the number of books that have a title ‘yyy’ .... ..... ....... 2013年7月24日星期三
  • 54. Add extra Manager methods # takes a keyword and returns the number of books >>> Book.objects.title_count('django') >>> Book.objects.title_count('python') 2013年7月24日星期三
  • 55. # 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) objects = BookManager() def __unicode__(self): return self.title 2013年7月24日星期三
  • 56. # 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) objects = BookManager() def __unicode__(self): return self.title 2013年7月24日星期三
  • 58. Modify initial Manager QuerySets Default Manager return all the records Override Manager’s base QuerySets 2013年7月24日星期三
  • 59. Modify initial Manager QuerySets Default Manager return all the records Override Manager’s base QuerySets # returns all books in the book database >>> Book.objects.all() 2013年7月24日星期三
  • 60. Modify initial Manager QuerySets Default Manager return all the records Override Manager’s base QuerySets By overriding the Manager.get_query_set() 2013年7月24日星期三
  • 61. Modify initial Manager QuerySets 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 Dahl-specific manager. 2013年7月24日星期三
  • 62. Modify initial Manager QuerySets 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 Dahl-specific manager. 2013年7月24日星期三
  • 63. Modify initial Manager QuerySets >>> Book.dahl_objects.all() >>> Book.dahl_objects.filter(title='Matilda') >>> Book.dahl_objects.count() 2013年7月24日星期三
  • 64. Another example 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() 2013年7月24日星期三
  • 65. Another example 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() 2013年7月24日星期三
  • 66. Modify initial Manager QuerySets >>> Person.men.all() >>> Person.women.all() >>> Person.people.all() 2013年7月24日星期三
  • 69. connection object cursor object cursor.execute() cursor.fetchone() / cursor.fetchall() Implement the Python DB-API (PEP-0249) Django DB objects 2013年7月24日星期三
  • 70. Execute raw SQL queries >>> 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'] 2013年7月24日星期三
  • 71. Execute raw SQL queries 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()] class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) objects = PersonManager() 2013年7月24日星期三
  • 72. Execute raw SQL queries 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()] class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) objects = PersonManager() 2013年7月24日星期三
  • 73. Execute raw SQL queries 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()] class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) objects = PersonManager() 2013年7月24日星期三
  • 74. Execute raw SQL queries >>> Person.objects.first_names('Lennon') ['John', 'Cynthia'] 2013年7月24日星期三
  • 77. Business logic encapsulation Add custom Managers Override default Manager with custom methods 2013年7月24日星期三
  • 78. Add custom Managers class IncompleteTodoManager(models.Manager): def get_query_set(self): return super(TodoManager, self).get_query_set().filter(is_done=False) class HighPriorityTodoManager(models.Manager): def get_query_set(self): return super(TodoManager, self).get_query_set().filter(priority=1) class Todo(models.Model): content = models.CharField(max_length=100) # other fields go here.. objects = models.Manager() # the default manager # attach our custom managers: incomplete = models.IncompleteTodoManager() high_priority = models.HighPriorityTodoManager() 2013年7月24日星期三
  • 79. Add custom Managers class IncompleteTodoManager(models.Manager): def get_query_set(self): return super(TodoManager, self).get_query_set().filter(is_done=False) class HighPriorityTodoManager(models.Manager): def get_query_set(self): return super(TodoManager, self).get_query_set().filter(priority=1) class Todo(models.Model): content = models.CharField(max_length=100) # other fields go here.. objects = models.Manager() # the default manager # attach our custom managers: incomplete = models.IncompleteTodoManager() high_priority = models.HighPriorityTodoManager() 2013年7月24日星期三
  • 80. Add custom Managers >>> Todo.incomplete.all() >>> Todo.high_priority.all() 2013年7月24日星期三
  • 82. Drawbacks Verbose Managers Cluttered model namespace Not chainable 2013年7月24日星期三
  • 84. Custom Manager methods class TodoManager(models.Manager): def incomplete(self): return self.filter(is_done=False) def high_priority(self): return self.filter(priority=1) class Todo(models.Model): content = models.CharField(max_length=100) # other fields go here.. objects = TodoManager() 2013年7月24日星期三
  • 85. Custom Manager methods >>> Todo.objects.incomplete() >>> Todo.objects.high_priority() 2013年7月24日星期三
  • 87. Drawbacks Not chainable between custom methods. # It didn’t work ! >>> Todo.objects.incomplete().high_priority() 2013年7月24日星期三
  • 89. Custom QuerySets class TodoQuerySet(models.query.QuerySet): def incomplete(self): return self.filter(is_done=False) def high_priority(self): return self.filter(priority=1) class TodoManager(models.Manager): def get_query_set(self): return TodoQuerySet(self.model, using=self._db) class Todo(models.Model): content = models.CharField(max_length=100) # other fields go here.. objects = TodoManager() 2013年7月24日星期三
  • 90. Custom QuerySets class TodoQuerySet(models.query.QuerySet): def incomplete(self): return self.filter(is_done=False) def high_priority(self): return self.filter(priority=1) class TodoManager(models.Manager): def get_query_set(self): return TodoQuerySet(self.model, using=self._db) class Todo(models.Model): content = models.CharField(max_length=100) # other fields go here.. objects = TodoManager() 2013年7月24日星期三
  • 91. Custom QuerySets >>> Todo.objects.get_query_set().incomplete() >>> Todo.objects.get_query_set().high_priority() >>> # (or) >>> Todo.objects.all().incomplete() >>> Todo.objects.all().high_priority() >>> # Chainable !!! >>> Todo.objects.all().incomplete().high_priority() 2013年7月24日星期三
  • 93. Custom QuerySets >>> Todo.objects.get_query_set().incomplete() >>> Todo.objects.get_query_set().high_priority() >>> # (or) >>> Todo.objects.all().incomplete() >>> Todo.objects.all().high_priority() >>> # Chainable !!! >>> Todo.objects.all().incomplete().high_priority() 2013年7月24日星期三
  • 94. Custom QuerySets >>> Todo.objects.get_query_set().incomplete() >>> Todo.objects.get_query_set().high_priority() >>> # (or) >>> Todo.objects.all().incomplete() >>> Todo.objects.all().high_priority() >>> # Chainable !!! >>> Todo.objects.all().incomplete().high_priority() Ug==Ugly !! 2013年7月24日星期三
  • 96. Proxy everything !! class TodoQuerySet(models.query.QuerySet): def incomplete(self): return self.filter(is_done=False) def high_priority(self): return self.filter(priority=1) class TodoManager(models.Manager): def get_query_set(self): return TodoQuerySet(self.model, using=self._db) def incomplete(self): return self.get_query_set().incomplete() def high_priority(self): return self.get_query_set().high_priority() 2013年7月24日星期三
  • 97. Proxy everything !! class TodoQuerySet(models.query.QuerySet): def incomplete(self): return self.filter(is_done=False) def high_priority(self): return self.filter(priority=1) class TodoManager(models.Manager): def get_query_set(self): return TodoQuerySet(self.model, using=self._db) def incomplete(self): return self.get_query_set().incomplete() def high_priority(self): return self.get_query_set().high_priority() 2013年7月24日星期三
  • 98. Proxy everything !! >>> Todo.objects.incomplete().high_priority() # Perfect !! 2013年7月24日星期三