Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/db/models/manager.py: 88%
99 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import copy
2import inspect
3from importlib import import_module
5from django.db import router
6from django.db.models.query import QuerySet
9class BaseManager:
10 # To retain order, track each time a Manager instance is created.
11 creation_counter = 0
13 # Set to True for the 'objects' managers that are automatically created.
14 auto_created = False
16 #: If set to True the manager will be serialized into migrations and will
17 #: thus be available in e.g. RunPython operations.
18 use_in_migrations = False
20 def __new__(cls, *args, **kwargs):
21 # Capture the arguments to make returning them trivial.
22 obj = super().__new__(cls)
23 obj._constructor_args = (args, kwargs)
24 return obj
26 def __init__(self):
27 super().__init__()
28 self._set_creation_counter()
29 self.model = None
30 self.name = None
31 self._db = None
32 self._hints = {}
34 def __str__(self):
35 """Return "app_label.model_label.manager_name"."""
36 return "%s.%s" % (self.model._meta.label, self.name)
38 def __class_getitem__(cls, *args, **kwargs):
39 return cls
41 def deconstruct(self):
42 """
43 Return a 5-tuple of the form (as_manager (True), manager_class,
44 queryset_class, args, kwargs).
46 Raise a ValueError if the manager is dynamically generated.
47 """
48 qs_class = self._queryset_class
49 if getattr(self, "_built_with_as_manager", False): 49 ↛ 51line 49 didn't jump to line 51, because the condition on line 49 was never true
50 # using MyQuerySet.as_manager()
51 return (
52 True, # as_manager
53 None, # manager_class
54 "%s.%s" % (qs_class.__module__, qs_class.__name__), # qs_class
55 None, # args
56 None, # kwargs
57 )
58 else:
59 module_name = self.__module__
60 name = self.__class__.__name__
61 # Make sure it's actually there and not an inner class
62 module = import_module(module_name)
63 if not hasattr(module, name): 63 ↛ 64line 63 didn't jump to line 64, because the condition on line 63 was never true
64 raise ValueError(
65 "Could not find manager %s in %s.\n"
66 "Please note that you need to inherit from managers you "
67 "dynamically generated with 'from_queryset()'."
68 % (name, module_name)
69 )
70 return (
71 False, # as_manager
72 "%s.%s" % (module_name, name), # manager_class
73 None, # qs_class
74 self._constructor_args[0], # args
75 self._constructor_args[1], # kwargs
76 )
78 def check(self, **kwargs):
79 return []
81 @classmethod
82 def _get_queryset_methods(cls, queryset_class):
83 def create_method(name, method):
84 def manager_method(self, *args, **kwargs):
85 return getattr(self.get_queryset(), name)(*args, **kwargs)
87 manager_method.__name__ = method.__name__
88 manager_method.__doc__ = method.__doc__
89 return manager_method
91 new_methods = {}
92 for name, method in inspect.getmembers(
93 queryset_class, predicate=inspect.isfunction
94 ):
95 # Only copy missing methods.
96 if hasattr(cls, name):
97 continue
98 # Only copy public methods or methods with the attribute
99 # queryset_only=False.
100 queryset_only = getattr(method, "queryset_only", None)
101 if queryset_only or (queryset_only is None and name.startswith("_")):
102 continue
103 # Copy the method onto the manager.
104 new_methods[name] = create_method(name, method)
105 return new_methods
107 @classmethod
108 def from_queryset(cls, queryset_class, class_name=None):
109 if class_name is None: 109 ↛ 111line 109 didn't jump to line 111, because the condition on line 109 was never false
110 class_name = "%sFrom%s" % (cls.__name__, queryset_class.__name__)
111 return type(
112 class_name,
113 (cls,),
114 {
115 "_queryset_class": queryset_class,
116 **cls._get_queryset_methods(queryset_class),
117 },
118 )
120 def contribute_to_class(self, cls, name):
121 self.name = self.name or name
122 self.model = cls
124 setattr(cls, name, ManagerDescriptor(self))
126 cls._meta.add_manager(self)
128 def _set_creation_counter(self):
129 """
130 Set the creation counter value for this instance and increment the
131 class-level copy.
132 """
133 self.creation_counter = BaseManager.creation_counter
134 BaseManager.creation_counter += 1
136 def db_manager(self, using=None, hints=None):
137 obj = copy.copy(self)
138 obj._db = using or self._db
139 obj._hints = hints or self._hints
140 return obj
142 @property
143 def db(self):
144 return self._db or router.db_for_read(self.model, **self._hints)
146 #######################
147 # PROXIES TO QUERYSET #
148 #######################
150 def get_queryset(self):
151 """
152 Return a new QuerySet object. Subclasses can override this method to
153 customize the behavior of the Manager.
154 """
155 return self._queryset_class(model=self.model, using=self._db, hints=self._hints)
157 def all(self):
158 # We can't proxy this method through the `QuerySet` like we do for the
159 # rest of the `QuerySet` methods. This is because `QuerySet.all()`
160 # works by creating a "copy" of the current queryset and in making said
161 # copy, all the cached `prefetch_related` lookups are lost. See the
162 # implementation of `RelatedManager.get_queryset()` for a better
163 # understanding of how this comes into play.
164 return self.get_queryset()
166 def __eq__(self, other):
167 return (
168 isinstance(other, self.__class__)
169 and self._constructor_args == other._constructor_args
170 )
172 def __hash__(self):
173 return id(self)
176class Manager(BaseManager.from_queryset(QuerySet)):
177 pass
180class ManagerDescriptor:
181 def __init__(self, manager):
182 self.manager = manager
184 def __get__(self, instance, cls=None):
185 if instance is not None: 185 ↛ 186line 185 didn't jump to line 186, because the condition on line 185 was never true
186 raise AttributeError(
187 "Manager isn't accessible via %s instances" % cls.__name__
188 )
190 if cls._meta.abstract: 190 ↛ 191line 190 didn't jump to line 191, because the condition on line 190 was never true
191 raise AttributeError(
192 "Manager isn't available; %s is abstract" % (cls._meta.object_name,)
193 )
195 if cls._meta.swapped: 195 ↛ 196line 195 didn't jump to line 196, because the condition on line 195 was never true
196 raise AttributeError(
197 "Manager isn't available; '%s' has been swapped for '%s'"
198 % (
199 cls._meta.label,
200 cls._meta.swapped,
201 )
202 )
204 return cls._meta.managers_map[self.manager.name]
207class EmptyManager(Manager):
208 def __init__(self, model):
209 super().__init__()
210 self.model = model
212 def get_queryset(self):
213 return super().get_queryset().none()