99
Advanced Models The Django BookChapter 10 Spin Lai July 23, 2013 2013年7月24日星期三

The django book - Chap10 : Advanced Models

Embed Size (px)

Citation preview

Page 1: The django book - Chap10 : Advanced Models

Advanced Models

「The Django Book」 Chapter 10

Spin Lai

July 23, 20132013年7月24日星期三

Page 2: The django book - Chap10 : Advanced Models

賴司平 (Spin)

資拓宏宇 氣象科技事業處

PHP、Javascript、Python

About me

2013年7月24日星期三

Page 3: The django book - Chap10 : Advanced Models

Related objects Update database schema Model methods Managers Execute raw SQL queries More about Managers

Today’s topics

2013年7月24日星期三

Page 4: The django book - Chap10 : Advanced Models

Related objects

2013年7月24日星期三

Page 5: The django book - Chap10 : Advanced Models

Recalling the Chapter 5 ...

2013年7月24日星期三

Page 6: The django book - Chap10 : Advanced Models

Publisheridnameaddresscitystate_provincecountrywebsite

AutoFieldCharFieldCharFieldCharFieldCharFieldCharFieldURLField

Bookidtitleauthorspublisherpublication_date

AutoFieldCharFieldManyToManyFieldForeignKeyDateField

Authoridfirst_namelast_nameemail

AutoFieldCharFieldCharFieldEmailField

N:1N:M

2013年7月24日星期三

Page 7: The django book - Chap10 : Advanced Models

class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField()

def __unicode__(self): return self.name

2013年7月24日星期三

Page 8: The django book - Chap10 : Advanced Models

class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField()

def __unicode__(self): return u'%s %s' % (self.first_name,

self.last_name)

2013年7月24日星期三

Page 9: The django book - Chap10 : Advanced Models

class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()

def __unicode__(self): return self.title

2013年7月24日星期三

Page 10: The django book - Chap10 : Advanced Models

class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()

def __unicode__(self): return self.title

2013年7月24日星期三

Page 11: The django book - Chap10 : Advanced Models

Foreign Key Value

Publisheridnameaddresscitystate_provincecountrywebsite

AutoFieldCharFieldCharFieldCharFieldCharFieldCharFieldURLField

Bookidtitleauthorspublisher

AutoFieldCharFieldManyToManyFieldForeignKey

>>> b = Book.objects.get(id=50)>>> b.publisher<Publisher: Apress Publishing>>>> b.publisher.websiteu'http://www.apress.com/'<Publisher: Apress Publishing>

2013年7月24日星期三

Page 12: The django book - Chap10 : Advanced Models

Foreign Key Value

Publisheridnameaddresscitystate_provincecountrywebsite

AutoFieldCharFieldCharFieldCharFieldCharFieldCharFieldURLField

Bookidtitleauthorspublisher

AutoFieldCharFieldManyToManyFieldForeignKey

>>> 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日星期三

Page 13: The django book - Chap10 : Advanced Models

Foreign Key Value

Publisheridnameaddresscitystate_provincecountrywebsite

AutoFieldCharFieldCharFieldCharFieldCharFieldCharFieldURLField

Bookidtitleauthorspublisher

AutoFieldCharFieldManyToManyFieldForeignKey

>>> 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日星期三

Page 14: The django book - Chap10 : Advanced Models

class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()

def __unicode__(self): return self.title

2013年7月24日星期三

Page 15: The django book - Chap10 : Advanced Models

class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()

def __unicode__(self): return self.title

2013年7月24日星期三

Page 16: The django book - Chap10 : Advanced Models

Many-to-Many Values

Authoridfirst_namelast_nameemail

AutoFieldCharFieldCharFieldEmailField

Bookidtitleauthorspublisher

AutoFieldCharFieldManyToManyFieldForeignKey

>>> 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日星期三

Page 17: The django book - Chap10 : Advanced Models

Many-to-Many Values

Authoridfirst_namelast_nameemail

AutoFieldCharFieldCharFieldEmailField

Bookidtitleauthorspublisher

AutoFieldCharFieldManyToManyFieldForeignKey

>>> 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日星期三

Page 18: The django book - Chap10 : Advanced Models

Many-to-Many Values

Authoridfirst_namelast_nameemail

AutoFieldCharFieldCharFieldEmailField

Bookidtitleauthorspublisher

AutoFieldCharFieldManyToManyFieldForeignKey

>>> 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日星期三

Page 19: The django book - Chap10 : Advanced Models

Update database schema

2013年7月24日星期三

Page 20: The django book - Chap10 : Advanced Models

First of all

2013年7月24日星期三

Page 21: The django book - Chap10 : Advanced Models

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日星期三

Page 22: The django book - Chap10 : Advanced Models

`syncdb` only create tables for models which

have not yet been installed.

2013年7月24日星期三

Page 23: The django book - Chap10 : Advanced Models

Add model fields Remove model fields Remove models

Update database schema

2013年7月24日星期三

Page 24: The django book - Chap10 : Advanced Models

Add model fields

2013年7月24日星期三

Page 25: The django book - Chap10 : Advanced Models

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日星期三

Page 26: The django book - Chap10 : Advanced Models

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日星期三

Page 27: The django book - Chap10 : Advanced Models

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日星期三

Page 28: The django book - Chap10 : Advanced Models

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日星期三

Page 29: The django book - Chap10 : Advanced Models

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日星期三

Page 30: The django book - Chap10 : Advanced Models

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日星期三

Page 31: The django book - Chap10 : Advanced Models

Remove model fields

2013年7月24日星期三

Page 32: The django book - Chap10 : Advanced Models

Add model fields

Remove fields from the model Restart the web server Remove columns from the DB table

Remove Normal fields ...

2013年7月24日星期三

Page 33: The django book - Chap10 : Advanced Models

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日星期三

Page 34: The django book - Chap10 : Advanced Models

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日星期三

Page 35: The django book - Chap10 : Advanced Models

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日星期三

Page 36: The django book - Chap10 : Advanced Models

Remove models

2013年7月24日星期三

Page 37: The django book - Chap10 : Advanced Models

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日星期三

Page 38: The django book - Chap10 : Advanced Models

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日星期三

Page 39: The django book - Chap10 : Advanced Models

Model methods

2013年7月24日星期三

Page 40: The django book - Chap10 : Advanced Models

class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() address = models.CharField(max_length=100) city = models.CharField(max_length=50) state = USStateField() # Yes, this is U.S.-centric...

def baby_boomer_status(self): "Returns the person's 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日星期三

Page 41: The django book - Chap10 : Advanced Models

class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() address = models.CharField(max_length=100) city = models.CharField(max_length=50) state = USStateField() # Yes, this is U.S.-centric...

def baby_boomer_status(self): "Returns the person's 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日星期三

Page 42: The django book - Chap10 : Advanced Models

Model methods

>>> p = Person.objects.get(first_name='Barack', last_name='Obama')>>> p.birth_datedatetime.date(1961, 8, 4)>>> p.baby_boomer_status()'Baby boomer'>>> p.is_midwestern()True

2013年7月24日星期三

Page 43: The django book - Chap10 : Advanced Models

class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() address = models.CharField(max_length=100) city = models.CharField(max_length=50) state = USStateField() # Yes, this is U.S.-centric...

def baby_boomer_status(self): "Returns the person's 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日星期三

Page 44: The django book - Chap10 : Advanced Models

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日星期三

Page 45: The django book - Chap10 : Advanced Models

Managers

2013年7月24日星期三

Page 46: The django book - Chap10 : Advanced Models

What is Manager?

2013年7月24日星期三

Page 47: The django book - Chap10 : Advanced Models

Manager

Book.objects.all()

2013年7月24日星期三

Page 48: The django book - Chap10 : Advanced Models

Manager

Book.objects.all()

2013年7月24日星期三

Page 49: The django book - Chap10 : Advanced Models

Manager

“ The interface through which database query operations are provided to Django models. ”

2013年7月24日星期三

Page 50: The django book - Chap10 : Advanced Models

Why do we need a custom Manager?

2013年7月24日星期三

Page 51: The django book - Chap10 : Advanced Models

Add extra Manager methods Modify initial Manager QuerySets

Custom Mangers

2013年7月24日星期三

Page 52: The django book - Chap10 : Advanced Models

Add extra Manager methods

2013年7月24日星期三

Page 53: The django book - Chap10 : Advanced Models

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日星期三

Page 54: The django book - Chap10 : Advanced Models

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日星期三

Page 55: The django book - Chap10 : Advanced Models

# models.pyfrom 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日星期三

Page 56: The django book - Chap10 : Advanced Models

# models.pyfrom 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日星期三

Page 57: The django book - Chap10 : Advanced Models

Modify initial Manager QuerySets

2013年7月24日星期三

Page 58: The django book - Chap10 : Advanced Models

Modify initial Manager QuerySets

Default Manager return all the records Override Manager’s base QuerySets

2013年7月24日星期三

Page 59: The django book - Chap10 : Advanced Models

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日星期三

Page 60: The django book - Chap10 : Advanced Models

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日星期三

Page 61: The django book - Chap10 : Advanced Models

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日星期三

Page 62: The django book - Chap10 : Advanced Models

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日星期三

Page 63: The django book - Chap10 : Advanced Models

Modify initial Manager QuerySets

>>> Book.dahl_objects.all()>>> Book.dahl_objects.filter(title='Matilda')>>> Book.dahl_objects.count()

2013年7月24日星期三

Page 64: The django book - Chap10 : Advanced Models

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日星期三

Page 65: The django book - Chap10 : Advanced Models

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日星期三

Page 66: The django book - Chap10 : Advanced Models

Modify initial Manager QuerySets

>>> Person.men.all()>>> Person.women.all()>>> Person.people.all()

2013年7月24日星期三

Page 67: The django book - Chap10 : Advanced Models

Execute raw SQL queries

2013年7月24日星期三

Page 68: The django book - Chap10 : Advanced Models

Django DB objects

2013年7月24日星期三

Page 69: The django book - Chap10 : Advanced Models

connection object cursor object cursor.execute() cursor.fetchone() / cursor.fetchall() Implement the Python DB-API (PEP-0249)

Django DB objects

2013年7月24日星期三

Page 70: The django book - Chap10 : Advanced Models

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日星期三

Page 71: The django book - Chap10 : Advanced Models

Execute raw SQL queriesclass 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日星期三

Page 72: The django book - Chap10 : Advanced Models

Execute raw SQL queriesclass 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日星期三

Page 73: The django book - Chap10 : Advanced Models

Execute raw SQL queriesclass 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日星期三

Page 74: The django book - Chap10 : Advanced Models

Execute raw SQL queries

>>> Person.objects.first_names('Lennon')['John', 'Cynthia']

2013年7月24日星期三

Page 75: The django book - Chap10 : Advanced Models

More about Managers

2013年7月24日星期三

Page 76: The django book - Chap10 : Advanced Models

As mentioned previously...

2013年7月24日星期三

Page 77: The django book - Chap10 : Advanced Models

Business logic encapsulation

Add custom Managers Override default Manager with custom

methods

2013年7月24日星期三

Page 78: The django book - Chap10 : Advanced Models

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日星期三

Page 79: The django book - Chap10 : Advanced Models

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日星期三

Page 80: The django book - Chap10 : Advanced Models

Add custom Managers

>>> Todo.incomplete.all()>>> Todo.high_priority.all()

2013年7月24日星期三

Page 81: The django book - Chap10 : Advanced Models

But

2013年7月24日星期三

Page 82: The django book - Chap10 : Advanced Models

Drawbacks

Verbose Managers Cluttered model namespace Not chainable

2013年7月24日星期三

Page 83: The django book - Chap10 : Advanced Models

Custom Manager methods

2013年7月24日星期三

Page 84: The django book - Chap10 : Advanced Models

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日星期三

Page 85: The django book - Chap10 : Advanced Models

Custom Manager methods

>>> Todo.objects.incomplete()>>> Todo.objects.high_priority()

2013年7月24日星期三

Page 86: The django book - Chap10 : Advanced Models

But

2013年7月24日星期三

Page 87: The django book - Chap10 : Advanced Models

Drawbacks

Not chainable between custom methods.

# It didn’t work !>>> Todo.objects.incomplete().high_priority()

2013年7月24日星期三

Page 88: The django book - Chap10 : Advanced Models

Custom QuerySets

2013年7月24日星期三

Page 89: The django book - Chap10 : Advanced Models

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日星期三

Page 90: The django book - Chap10 : Advanced Models

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日星期三

Page 91: The django book - Chap10 : Advanced Models

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日星期三

Page 92: The django book - Chap10 : Advanced Models

But

2013年7月24日星期三

Page 93: The django book - Chap10 : Advanced Models

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日星期三

Page 94: The django book - Chap10 : Advanced Models

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日星期三

Page 95: The django book - Chap10 : Advanced Models

Proxy everything !!

2013年7月24日星期三

Page 96: The django book - Chap10 : Advanced Models

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日星期三

Page 97: The django book - Chap10 : Advanced Models

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日星期三

Page 98: The django book - Chap10 : Advanced Models

Proxy everything !!

>>> Todo.objects.incomplete().high_priority() # Perfect !!

2013年7月24日星期三

Page 99: The django book - Chap10 : Advanced Models

Thank you

2013年7月24日星期三