1 """ |
|
2 23. Giving models a custom manager |
|
3 |
|
4 You can use a custom ``Manager`` in a particular model by extending the base |
|
5 ``Manager`` class and instantiating your custom ``Manager`` in your model. |
|
6 |
|
7 There are two reasons you might want to customize a ``Manager``: to add extra |
|
8 ``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager`` |
|
9 returns. |
|
10 """ |
|
11 |
|
12 from django.db import models |
|
13 |
|
14 # An example of a custom manager called "objects". |
|
15 |
|
16 class PersonManager(models.Manager): |
|
17 def get_fun_people(self): |
|
18 return self.filter(fun=True) |
|
19 |
|
20 class Person(models.Model): |
|
21 first_name = models.CharField(maxlength=30) |
|
22 last_name = models.CharField(maxlength=30) |
|
23 fun = models.BooleanField() |
|
24 objects = PersonManager() |
|
25 |
|
26 def __str__(self): |
|
27 return "%s %s" % (self.first_name, self.last_name) |
|
28 |
|
29 # An example of a custom manager that sets get_query_set(). |
|
30 |
|
31 class PublishedBookManager(models.Manager): |
|
32 def get_query_set(self): |
|
33 return super(PublishedBookManager, self).get_query_set().filter(is_published=True) |
|
34 |
|
35 class Book(models.Model): |
|
36 title = models.CharField(maxlength=50) |
|
37 author = models.CharField(maxlength=30) |
|
38 is_published = models.BooleanField() |
|
39 published_objects = PublishedBookManager() |
|
40 authors = models.ManyToManyField(Person, related_name='books') |
|
41 |
|
42 def __str__(self): |
|
43 return self.title |
|
44 |
|
45 # An example of providing multiple custom managers. |
|
46 |
|
47 class FastCarManager(models.Manager): |
|
48 def get_query_set(self): |
|
49 return super(FastCarManager, self).get_query_set().filter(top_speed__gt=150) |
|
50 |
|
51 class Car(models.Model): |
|
52 name = models.CharField(maxlength=10) |
|
53 mileage = models.IntegerField() |
|
54 top_speed = models.IntegerField(help_text="In miles per hour.") |
|
55 cars = models.Manager() |
|
56 fast_cars = FastCarManager() |
|
57 |
|
58 def __str__(self): |
|
59 return self.name |
|
60 |
|
61 __test__ = {'API_TESTS':""" |
|
62 >>> p1 = Person(first_name='Bugs', last_name='Bunny', fun=True) |
|
63 >>> p1.save() |
|
64 >>> p2 = Person(first_name='Droopy', last_name='Dog', fun=False) |
|
65 >>> p2.save() |
|
66 >>> Person.objects.get_fun_people() |
|
67 [<Person: Bugs Bunny>] |
|
68 |
|
69 # The RelatedManager used on the 'books' descriptor extends the default manager |
|
70 >>> from modeltests.custom_managers.models import PublishedBookManager |
|
71 >>> isinstance(p2.books, PublishedBookManager) |
|
72 True |
|
73 |
|
74 >>> b1 = Book(title='How to program', author='Rodney Dangerfield', is_published=True) |
|
75 >>> b1.save() |
|
76 >>> b2 = Book(title='How to be smart', author='Albert Einstein', is_published=False) |
|
77 >>> b2.save() |
|
78 |
|
79 # The default manager, "objects", doesn't exist, |
|
80 # because a custom one was provided. |
|
81 >>> Book.objects |
|
82 Traceback (most recent call last): |
|
83 ... |
|
84 AttributeError: type object 'Book' has no attribute 'objects' |
|
85 |
|
86 # The RelatedManager used on the 'authors' descriptor extends the default manager |
|
87 >>> from modeltests.custom_managers.models import PersonManager |
|
88 >>> isinstance(b2.authors, PersonManager) |
|
89 True |
|
90 |
|
91 >>> Book.published_objects.all() |
|
92 [<Book: How to program>] |
|
93 |
|
94 >>> c1 = Car(name='Corvette', mileage=21, top_speed=180) |
|
95 >>> c1.save() |
|
96 >>> c2 = Car(name='Neon', mileage=31, top_speed=100) |
|
97 >>> c2.save() |
|
98 >>> Car.cars.order_by('name') |
|
99 [<Car: Corvette>, <Car: Neon>] |
|
100 >>> Car.fast_cars.all() |
|
101 [<Car: Corvette>] |
|
102 |
|
103 # Each model class gets a "_default_manager" attribute, which is a reference |
|
104 # to the first manager defined in the class. In this case, it's "cars". |
|
105 >>> Car._default_manager.order_by('name') |
|
106 [<Car: Corvette>, <Car: Neon>] |
|
107 """} |
|