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