app/django/db/models/manager.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
equal deleted inserted replaced
322:6641e941ef1e 323:ff1a9aa48cfd
     1 import copy
     1 import copy
     2 
     2 
     3 from django.db.models.query import QuerySet, EmptyQuerySet, insert_query
     3 from django.db.models.query import QuerySet, EmptyQuerySet, insert_query
     4 from django.dispatch import dispatcher
       
     5 from django.db.models import signals
     4 from django.db.models import signals
     6 from django.db.models.fields import FieldDoesNotExist
     5 from django.db.models.fields import FieldDoesNotExist
     7 
     6 
     8 def ensure_default_manager(sender):
     7 def ensure_default_manager(sender, **kwargs):
     9     cls = sender
     8     cls = sender
    10     if not getattr(cls, '_default_manager', None) and not cls._meta.abstract:
     9     if not getattr(cls, '_default_manager', None) and not cls._meta.abstract:
    11         # Create the default manager, if needed.
    10         # Create the default manager, if needed.
    12         try:
    11         try:
    13             cls._meta.get_field('objects')
    12             cls._meta.get_field('objects')
    14             raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % cls.__name__
    13             raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % cls.__name__
    15         except FieldDoesNotExist:
    14         except FieldDoesNotExist:
    16             pass
    15             pass
    17         cls.add_to_class('objects', Manager())
    16         cls.add_to_class('objects', Manager())
    18 
    17 
    19 dispatcher.connect(ensure_default_manager, signal=signals.class_prepared)
    18 signals.class_prepared.connect(ensure_default_manager)
    20 
    19 
    21 class Manager(object):
    20 class Manager(object):
    22     # Tracks each time a Manager instance is created. Used to retain order.
    21     # Tracks each time a Manager instance is created. Used to retain order.
    23     creation_counter = 0
    22     creation_counter = 0
    24 
    23 
    25     def __init__(self):
    24     def __init__(self):
    26         super(Manager, self).__init__()
    25         super(Manager, self).__init__()
    27         # Increase the creation counter, and save our local copy.
    26         self._set_creation_counter()
    28         self.creation_counter = Manager.creation_counter
       
    29         Manager.creation_counter += 1
       
    30         self.model = None
    27         self.model = None
       
    28         self._inherited = False
    31 
    29 
    32     def contribute_to_class(self, model, name):
    30     def contribute_to_class(self, model, name):
    33         # TODO: Use weakref because of possible memory leak / circular reference.
    31         # TODO: Use weakref because of possible memory leak / circular reference.
    34         self.model = model
    32         self.model = model
    35         setattr(model, name, ManagerDescriptor(self))
    33         setattr(model, name, ManagerDescriptor(self))
    36         if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
    34         if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
    37             model._default_manager = self
    35             model._default_manager = self
       
    36         if model._meta.abstract or self._inherited:
       
    37             model._meta.abstract_managers.append((self.creation_counter, name,
       
    38                     self))
       
    39 
       
    40     def _set_creation_counter(self):
       
    41         """
       
    42         Sets the creation counter value for this instance and increments the
       
    43         class-level copy.
       
    44         """
       
    45         self.creation_counter = Manager.creation_counter
       
    46         Manager.creation_counter += 1
    38 
    47 
    39     def _copy_to_model(self, model):
    48     def _copy_to_model(self, model):
    40         """
    49         """
    41         Makes a copy of the manager and assigns it to 'model', which should be
    50         Makes a copy of the manager and assigns it to 'model', which should be
    42         a child of the existing model (used when inheriting a manager from an
    51         a child of the existing model (used when inheriting a manager from an
    43         abstract base class).
    52         abstract base class).
    44         """
    53         """
    45         assert issubclass(model, self.model)
    54         assert issubclass(model, self.model)
    46         mgr = copy.copy(self)
    55         mgr = copy.copy(self)
       
    56         mgr._set_creation_counter()
    47         mgr.model = model
    57         mgr.model = model
       
    58         mgr._inherited = True
    48         return mgr
    59         return mgr
    49 
    60 
    50     #######################
    61     #######################
    51     # PROXIES TO QUERYSET #
    62     # PROXIES TO QUERYSET #
    52     #######################
    63     #######################