Your SlideShare is downloading. ×
0
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	 Mana...
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
...
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = mod...
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email...
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = mo...
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = mo...
Foreign Key Value
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
Ch...
Foreign Key Value
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
Ch...
Foreign Key Value
Publisher
id
name
address
city
state_province
country
website
AutoField
CharField
CharField
CharField
Ch...
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = mo...
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = mo...
Many-to-Many Values
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
Book
id
title
authors
pub...
Many-to-Many Values
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
Book
id
title
authors
pub...
Many-to-Many Values
Author
id
first_name
last_name
email
AutoField
CharField
CharField
EmailField
Book
id
title
authors
pub...
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...
`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 ne...
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify ne...
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify ne...
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify ne...
Add model fields
Add fields to the model
Check the column definitions for new fields
Add new columns to the DB table
Verify ne...
Add model fields
Add new columns to the DB table
Add fields to the model
Restart the web server
In production environments ....
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 .....
Add model fields
Remove fields from the model
Restart the web server
Remove columns from the DB table
Remove Normal fields .....
Add model fields
Remove Many-to-Many fields from the model
Restart the web server
Remove Many-to-Many table from the DB
Remo...
Add model fields
Remove Many-to-Many fields from the model
Restart the web server
Remove Many-to-Many table from the DB
Remo...
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 th...
Remove model from the `models.py`
Restart the web server
Remove dependent tables from the DB
Remove the target table from ...
Model methods
2013年7月24日星期三
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth...
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth...
Model methods
>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.birth_date
datetime.date(1961, 8, 4...
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth...
Property methods
>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.full_name # Note this isn't a me...
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='D...
Add extra Manager methods
# takes a keyword and returns the number of books
>>> Book.objects.title_count('django')
>>> Boo...
# models.py
from django.db import models
# ... Author and Publisher models here ...
class BookManager(models.Manager):
def...
# models.py
from django.db import models
# ... Author and Publisher models here ...
class BookManager(models.Manager):
def...
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 bo...
Modify initial Manager QuerySets
Default Manager return all the records
Override Manager’s base QuerySets
By overriding th...
Modify initial Manager QuerySets
from django.db import models
# First, define the Manager subclass.
class DahlBookManager(...
Modify initial Manager QuerySets
from django.db import models
# First, define the Manager subclass.
class DahlBookManager(...
Modify initial Manager QuerySets
>>> Book.dahl_objects.all()
>>> Book.dahl_objects.filter(title='Matilda')
>>> Book.dahl_o...
Another example
class MaleManager(models.Manager):
def get_query_set(self):
return super(MaleManager, self).get_query_set(...
Another example
class MaleManager(models.Manager):
def get_query_set(self):
return super(MaleManager, self).get_query_set(...
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-02...
Execute raw SQL queries
>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute("""
... S...
Execute raw SQL queries
class PersonManager(models.Manager):
def first_names(self, last_name):
cursor = connection.cursor(...
Execute raw SQL queries
class PersonManager(models.Manager):
def first_names(self, last_name):
cursor = connection.cursor(...
Execute raw SQL queries
class PersonManager(models.Manager):
def first_names(self, last_name):
cursor = connection.cursor(...
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)....
Add custom Managers
class IncompleteTodoManager(models.Manager):
def get_query_set(self):
return super(TodoManager, self)....
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...
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 hi...
Custom QuerySets
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def hi...
Custom QuerySets
>>> Todo.objects.get_query_set().incomplete()
>>> Todo.objects.get_query_set().high_priority()
>>> # (or)...
But
2013年7月24日星期三
Custom QuerySets
>>> Todo.objects.get_query_set().incomplete()
>>> Todo.objects.get_query_set().high_priority()
>>> # (or)...
Custom QuerySets
>>> Todo.objects.get_query_set().incomplete()
>>> Todo.objects.get_query_set().high_priority()
>>> # (or)...
Proxy everything !!
2013年7月24日星期三
Proxy everything !!
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def...
Proxy everything !!
class TodoQuerySet(models.query.QuerySet):
def incomplete(self):
return self.filter(is_done=False)
def...
Proxy everything !!
>>> Todo.objects.incomplete().high_priority() # Perfect !!
2013年7月24日星期三
Thank you
2013年7月24日星期三
Upcoming SlideShare
Loading in...5
×

The django book - Chap10 : Advanced Models

1,482

Published on

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,482
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
29
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "The django book - Chap10 : Advanced Models"

  1. 1. Advanced Models 「The Django Book」 Chapter 10 Spin Lai July 23, 2013 2013年7月24日星期三
  2. 2. 賴司平 (Spin) 資拓宏宇 氣象科技事業處 PHP、Javascript、Python About me 2013年7月24日星期三
  3. 3. Related objects Update database schema Model methods Managers Execute raw SQL queries More about Managers Today’s topics 2013年7月24日星期三
  4. 4. Related objects 2013年7月24日星期三
  5. 5. Recalling the Chapter 5 ... 2013年7月24日星期三
  6. 6. 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日星期三
  7. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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日星期三
  19. 19. Update database schema 2013年7月24日星期三
  20. 20. First of all 2013年7月24日星期三
  21. 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. 22. `syncdb` only create tables for models which have not yet been installed. 2013年7月24日星期三
  23. 23. Add model fields Remove model fields Remove models Update database schema 2013年7月24日星期三
  24. 24. Add model fields 2013年7月24日星期三
  25. 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. 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. 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. 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. 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. 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日星期三
  31. 31. Remove model fields 2013年7月24日星期三
  32. 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. 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. 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. 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日星期三
  36. 36. Remove models 2013年7月24日星期三
  37. 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. 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日星期三
  39. 39. Model methods 2013年7月24日星期三
  40. 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. 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. 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. 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. 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日星期三
  45. 45. Managers 2013年7月24日星期三
  46. 46. What is Manager? 2013年7月24日星期三
  47. 47. Manager Book.objects.all() 2013年7月24日星期三
  48. 48. Manager Book.objects.all() 2013年7月24日星期三
  49. 49. Manager “ The interface through which database query operations are provided to Django models. ” 2013年7月24日星期三
  50. 50. Why do we need a custom Manager? 2013年7月24日星期三
  51. 51. Add extra Manager methods Modify initial Manager QuerySets Custom Mangers 2013年7月24日星期三
  52. 52. Add extra Manager methods 2013年7月24日星期三
  53. 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. 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. 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. 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日星期三
  57. 57. Modify initial Manager QuerySets 2013年7月24日星期三
  58. 58. Modify initial Manager QuerySets Default Manager return all the records Override Manager’s base QuerySets 2013年7月24日星期三
  59. 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. 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. 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. 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. 63. Modify initial Manager QuerySets >>> Book.dahl_objects.all() >>> Book.dahl_objects.filter(title='Matilda') >>> Book.dahl_objects.count() 2013年7月24日星期三
  64. 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. 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. 66. Modify initial Manager QuerySets >>> Person.men.all() >>> Person.women.all() >>> Person.people.all() 2013年7月24日星期三
  67. 67. Execute raw SQL queries 2013年7月24日星期三
  68. 68. Django DB objects 2013年7月24日星期三
  69. 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. 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. 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. 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. 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. 74. Execute raw SQL queries >>> Person.objects.first_names('Lennon') ['John', 'Cynthia'] 2013年7月24日星期三
  75. 75. More about Managers 2013年7月24日星期三
  76. 76. As mentioned previously... 2013年7月24日星期三
  77. 77. Business logic encapsulation Add custom Managers Override default Manager with custom methods 2013年7月24日星期三
  78. 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. 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. 80. Add custom Managers >>> Todo.incomplete.all() >>> Todo.high_priority.all() 2013年7月24日星期三
  81. 81. But 2013年7月24日星期三
  82. 82. Drawbacks Verbose Managers Cluttered model namespace Not chainable 2013年7月24日星期三
  83. 83. Custom Manager methods 2013年7月24日星期三
  84. 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. 85. Custom Manager methods >>> Todo.objects.incomplete() >>> Todo.objects.high_priority() 2013年7月24日星期三
  86. 86. But 2013年7月24日星期三
  87. 87. Drawbacks Not chainable between custom methods. # It didn’t work ! >>> Todo.objects.incomplete().high_priority() 2013年7月24日星期三
  88. 88. Custom QuerySets 2013年7月24日星期三
  89. 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. 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. 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日星期三
  92. 92. But 2013年7月24日星期三
  93. 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. 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日星期三
  95. 95. Proxy everything !! 2013年7月24日星期三
  96. 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. 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. 98. Proxy everything !! >>> Todo.objects.incomplete().high_priority() # Perfect !! 2013年7月24日星期三
  99. 99. Thank you 2013年7月24日星期三
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×