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:
parent
cdeebb33f5
commit
e2dfad15f1
@ -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)
|
||||
|
||||
|
@ -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 #
|
||||
#######################
|
||||
|
Loading…
x
Reference in New Issue
Block a user