Ticket #17270: manager.2.py

File manager.2.py, 3.5 KB (added by Wojciech Banaś <fizista@…>, 13 years ago)

Improved and simplified version.

Line 
1from types import MethodType
2from django.db import models
3from django.db.models.query import QuerySet
4from django.db.models.query import EmptyQuerySet
5
6class ManagerQuerySetDecorator(models.Manager):
7 """
8 Extends the operation methods of the manager on subqueries QuerySet objects.
9
10 The "standard manager" you can only like this:
11 SomeModel.object.some_method_manager().all().filter(...). ...
12
13 But this does not work:
14 SomeModel.object.all().some_method_manager()
15
16 And this it works with the use of this class / patches:
17 SomeModel.object.all().some_method_manager().filter(...).some_method_manager2(). ...
18 SomeModel.object.some_method_manager().some_method_manager2().some_method_manager3(). ...
19
20 Extension of the methods manager on all child objects "QuerySeth".
21
22 Example:
23
24 class Animals(models.Model):
25 type = models.CharField('Type of animal') # dog, cat, elephant
26 color = models.CharField('Colour Name')
27
28 objects = AnimalsManager()
29
30 class AnimalsManager(ManagerQuerySetDecorator):
31
32 def get_dogs(self):
33 return self.get_query_set().filter(type='dog')
34 get_dogs.queryset_method = True
35
36 def get_cats(self):
37 return self.get_query_set().filter(type='cat')
38 get_cats.queryset_method = True
39
40 def get_white_animals(self):
41 return self.get_query_set().filter(color='white')
42 get_white_animals.queryset_method = True
43
44 def get_black_animals(self):
45 return self.get_query_set().filter(color='black')
46 get_black_animals.queryset_method = True
47
48 def get_brown_animals(self):
49 return self.get_query_set().filter(color='black')
50
51
52 Animals(type='dog', color='black').save()
53 Animals(type='dog', color='bown').save()
54 Animals(type='dog', color='white').save()
55 Animals(type='cat', color='black').save()
56 Animals(type='cat', color='bown').save()
57 Animals(type='cat', color='white').save()
58
59 animals = Animals.objects.get_black_animals().get_dogs()
60 # return list black dogs
61
62 animals = Animals.objects.get_white_animals().get_cats()
63 # return list white cats
64
65 # When ffff equals False, or not defined (as it is in
66 # the original model manager), we can not perform such an operation:
67 animals = Animals.objects.get_cats().get_brown_animals()
68 # return:
69 # AttributeError: 'QuerySet' object has no attribute 'get_brown_animals'
70
71 # but:
72 animals = Animals.objects.get_brown_animals().get_cats()
73 # return brown cats, because get_cat() present in all parent object instances.
74 """
75
76 def _get_queryset_class(self):
77 class ManagerQuerySet(QuerySet):
78 def none(self):
79 """
80 Returns an empty QuerySet.
81 """
82 klass = type(
83 "_InstrumentedEmptyQuerySet_%s" % self.__class__.__name__,
84 (EmptyQuerySet, self.__class__), {})
85 return self._clone(klass=klass)
86 for attrib_name in dir(self):
87 attrib = getattr(self,attrib_name)
88 if isinstance(attrib, MethodType) and hasattr(attrib, 'queryset_method') and attrib.queryset_method:
89 setattr(ManagerQuerySet, attrib_name, attrib)
90 return ManagerQuerySet
91
92 def get_query_set(self):
93 return self._get_queryset_class()(self.model, using=self._db)
94
95
Back to Top