1
0
mirror of https://github.com/django/django.git synced 2025-07-05 18:29:11 +00:00

queyrset-refactor: Allow default managers to be inherited from an abstract base

class, unless the child class defines its own manager (i.e. child has first
chance to define the default). All managers were already inherited. This just
changes how the default is set in the case when the child defines no manager
and an abstract parent does.


git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7339 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-03-20 16:10:51 +00:00
parent cdeebb33f5
commit e2dfad15f1
2 changed files with 24 additions and 7 deletions

View File

@ -3,8 +3,8 @@ import sys
import os
from itertools import izip
import django.db.models.manipulators
import django.db.models.manager
import django.db.models.manipulators # Imported to register signal handler.
import django.db.models.manager # Ditto.
from django.core import validators
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
@ -59,9 +59,11 @@ class ModelBase(type):
if not hasattr(meta, 'get_latest_by'):
new_class._meta.get_latest_by = base_meta.get_latest_by
if getattr(new_class, '_default_manager', None) is not None:
# We have a parent who set the default manager. We need to override
# this.
old_default_mgr = None
if getattr(new_class, '_default_manager', None):
# We have a parent who set the default manager.
if new_class._default_manager.model._meta.abstract:
old_default_mgr = new_class._default_manager
new_class._default_manager = None
if getattr(new_class._meta, 'app_label', None) is None:
# Figure out the app_label by looking one level up.
@ -113,6 +115,8 @@ class ModelBase(type):
new_class.Meta = attr_meta
return new_class
if old_default_mgr and not new_class._default_manager:
new_class._default_manager = old_default_mgr._copy_to_model(new_class)
new_class._prepare()
register_models(new_class._meta.app_label, new_class)

View File

@ -1,3 +1,5 @@
import copy
from django.db.models.query import QuerySet, EmptyQuerySet, insert_query
from django.dispatch import dispatcher
from django.db.models import signals
@ -5,7 +7,7 @@ from django.db.models.fields import FieldDoesNotExist
def ensure_default_manager(sender):
cls = sender
if not hasattr(cls, '_default_manager') or cls._default_manager is None:
if not getattr(cls, '_default_manager', None) and not cls._meta.abstract:
# Create the default manager, if needed.
try:
cls._meta.get_field('objects')
@ -31,9 +33,20 @@ class Manager(object):
# TODO: Use weakref because of possible memory leak / circular reference.
self.model = model
setattr(model, name, ManagerDescriptor(self))
if not hasattr(model, '_default_manager') or model._default_manager is None or self.creation_counter < model._default_manager.creation_counter:
if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
model._default_manager = self
def _copy_to_model(self, model):
"""
Makes a copy of the manager and assigns it to 'model', which should be
a child of the existing model (used when inheriting a manager from an
abstract base class).
"""
assert issubclass(model, self.model)
mgr = copy.copy(self)
mgr.model = model
return mgr
#######################
# PROXIES TO QUERYSET #
#######################