web/lib/django/db/models/manager.py
changeset 0 0d40e90630ef
child 29 cc9b7e14412b
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     1 import copy
       
     2 
       
     3 from django.db.models.query import QuerySet, EmptyQuerySet, insert_query
       
     4 from django.db.models import signals
       
     5 from django.db.models.fields import FieldDoesNotExist
       
     6 
       
     7 def ensure_default_manager(sender, **kwargs):
       
     8     """
       
     9     Ensures that a Model subclass contains a default manager  and sets the
       
    10     _default_manager attribute on the class. Also sets up the _base_manager
       
    11     points to a plain Manager instance (which could be the same as
       
    12     _default_manager if it's not a subclass of Manager).
       
    13     """
       
    14     cls = sender
       
    15     if cls._meta.abstract:
       
    16         return
       
    17     if not getattr(cls, '_default_manager', None):
       
    18         # Create the default manager, if needed.
       
    19         try:
       
    20             cls._meta.get_field('objects')
       
    21             raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % cls.__name__
       
    22         except FieldDoesNotExist:
       
    23             pass
       
    24         cls.add_to_class('objects', Manager())
       
    25         cls._base_manager = cls.objects
       
    26     elif not getattr(cls, '_base_manager', None):
       
    27         default_mgr = cls._default_manager.__class__
       
    28         if (default_mgr is Manager or
       
    29                 getattr(default_mgr, "use_for_related_fields", False)):
       
    30             cls._base_manager = cls._default_manager
       
    31         else:
       
    32             # Default manager isn't a plain Manager class, or a suitable
       
    33             # replacement, so we walk up the base class hierarchy until we hit
       
    34             # something appropriate.
       
    35             for base_class in default_mgr.mro()[1:]:
       
    36                 if (base_class is Manager or
       
    37                         getattr(base_class, "use_for_related_fields", False)):
       
    38                     cls.add_to_class('_base_manager', base_class())
       
    39                     return
       
    40             raise AssertionError("Should never get here. Please report a bug, including your model and model manager setup.")
       
    41 
       
    42 signals.class_prepared.connect(ensure_default_manager)
       
    43 
       
    44 class Manager(object):
       
    45     # Tracks each time a Manager instance is created. Used to retain order.
       
    46     creation_counter = 0
       
    47 
       
    48     def __init__(self):
       
    49         super(Manager, self).__init__()
       
    50         self._set_creation_counter()
       
    51         self.model = None
       
    52         self._inherited = False
       
    53 
       
    54     def contribute_to_class(self, model, name):
       
    55         # TODO: Use weakref because of possible memory leak / circular reference.
       
    56         self.model = model
       
    57         setattr(model, name, ManagerDescriptor(self))
       
    58         if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
       
    59             model._default_manager = self
       
    60         if model._meta.abstract or (self._inherited and not self.model._meta.proxy):
       
    61             model._meta.abstract_managers.append((self.creation_counter, name,
       
    62                     self))
       
    63         else:
       
    64             model._meta.concrete_managers.append((self.creation_counter, name,
       
    65                 self))
       
    66 
       
    67     def _set_creation_counter(self):
       
    68         """
       
    69         Sets the creation counter value for this instance and increments the
       
    70         class-level copy.
       
    71         """
       
    72         self.creation_counter = Manager.creation_counter
       
    73         Manager.creation_counter += 1
       
    74 
       
    75     def _copy_to_model(self, model):
       
    76         """
       
    77         Makes a copy of the manager and assigns it to 'model', which should be
       
    78         a child of the existing model (used when inheriting a manager from an
       
    79         abstract base class).
       
    80         """
       
    81         assert issubclass(model, self.model)
       
    82         mgr = copy.copy(self)
       
    83         mgr._set_creation_counter()
       
    84         mgr.model = model
       
    85         mgr._inherited = True
       
    86         return mgr
       
    87 
       
    88     #######################
       
    89     # PROXIES TO QUERYSET #
       
    90     #######################
       
    91 
       
    92     def get_empty_query_set(self):
       
    93         return EmptyQuerySet(self.model)
       
    94 
       
    95     def get_query_set(self):
       
    96         """Returns a new QuerySet object.  Subclasses can override this method
       
    97         to easily customize the behavior of the Manager.
       
    98         """
       
    99         return QuerySet(self.model)
       
   100 
       
   101     def none(self):
       
   102         return self.get_empty_query_set()
       
   103 
       
   104     def all(self):
       
   105         return self.get_query_set()
       
   106 
       
   107     def count(self):
       
   108         return self.get_query_set().count()
       
   109 
       
   110     def dates(self, *args, **kwargs):
       
   111         return self.get_query_set().dates(*args, **kwargs)
       
   112 
       
   113     def distinct(self, *args, **kwargs):
       
   114         return self.get_query_set().distinct(*args, **kwargs)
       
   115 
       
   116     def extra(self, *args, **kwargs):
       
   117         return self.get_query_set().extra(*args, **kwargs)
       
   118 
       
   119     def get(self, *args, **kwargs):
       
   120         return self.get_query_set().get(*args, **kwargs)
       
   121 
       
   122     def get_or_create(self, **kwargs):
       
   123         return self.get_query_set().get_or_create(**kwargs)
       
   124 
       
   125     def create(self, **kwargs):
       
   126         return self.get_query_set().create(**kwargs)
       
   127 
       
   128     def filter(self, *args, **kwargs):
       
   129         return self.get_query_set().filter(*args, **kwargs)
       
   130 
       
   131     def aggregate(self, *args, **kwargs):
       
   132         return self.get_query_set().aggregate(*args, **kwargs)
       
   133 
       
   134     def annotate(self, *args, **kwargs):
       
   135         return self.get_query_set().annotate(*args, **kwargs)
       
   136 
       
   137     def complex_filter(self, *args, **kwargs):
       
   138         return self.get_query_set().complex_filter(*args, **kwargs)
       
   139 
       
   140     def exclude(self, *args, **kwargs):
       
   141         return self.get_query_set().exclude(*args, **kwargs)
       
   142 
       
   143     def in_bulk(self, *args, **kwargs):
       
   144         return self.get_query_set().in_bulk(*args, **kwargs)
       
   145 
       
   146     def iterator(self, *args, **kwargs):
       
   147         return self.get_query_set().iterator(*args, **kwargs)
       
   148 
       
   149     def latest(self, *args, **kwargs):
       
   150         return self.get_query_set().latest(*args, **kwargs)
       
   151 
       
   152     def order_by(self, *args, **kwargs):
       
   153         return self.get_query_set().order_by(*args, **kwargs)
       
   154 
       
   155     def select_related(self, *args, **kwargs):
       
   156         return self.get_query_set().select_related(*args, **kwargs)
       
   157 
       
   158     def values(self, *args, **kwargs):
       
   159         return self.get_query_set().values(*args, **kwargs)
       
   160 
       
   161     def values_list(self, *args, **kwargs):
       
   162         return self.get_query_set().values_list(*args, **kwargs)
       
   163 
       
   164     def update(self, *args, **kwargs):
       
   165         return self.get_query_set().update(*args, **kwargs)
       
   166 
       
   167     def reverse(self, *args, **kwargs):
       
   168         return self.get_query_set().reverse(*args, **kwargs)
       
   169 
       
   170     def defer(self, *args, **kwargs):
       
   171         return self.get_query_set().defer(*args, **kwargs)
       
   172 
       
   173     def only(self, *args, **kwargs):
       
   174         return self.get_query_set().only(*args, **kwargs)
       
   175 
       
   176     def _insert(self, values, **kwargs):
       
   177         return insert_query(self.model, values, **kwargs)
       
   178 
       
   179     def _update(self, values, **kwargs):
       
   180         return self.get_query_set()._update(values, **kwargs)
       
   181 
       
   182 class ManagerDescriptor(object):
       
   183     # This class ensures managers aren't accessible via model instances.
       
   184     # For example, Poll.objects works, but poll_obj.objects raises AttributeError.
       
   185     def __init__(self, manager):
       
   186         self.manager = manager
       
   187 
       
   188     def __get__(self, instance, type=None):
       
   189         if instance != None:
       
   190             raise AttributeError, "Manager isn't accessible via %s instances" % type.__name__
       
   191         return self.manager
       
   192 
       
   193 class EmptyManager(Manager):
       
   194     def get_query_set(self):
       
   195         return self.get_empty_query_set()