Ticket #7154: 0001-Now-all-managers-not-only-the-default-manager-gets.patch

File 0001-Now-all-managers-not-only-the-default-manager-gets.patch, 4.0 KB (added by Sebastian Noack, 16 years ago)
  • django/db/models/base.py

    From ad2eb44d297ed2b3decd59a97090ca70266f04c7 Mon Sep 17 00:00:00 2001
    From: Sebastian Noack <sebastian.noack@gmail.com>
    Date: Fri, 2 May 2008 13:22:20 +0200
    Subject: [PATCH] Now all managers, not only the default manager gets copied to the derived model of an abstract model.
    
    ---
     django/db/models/base.py    |   16 +++++++---------
     django/db/models/manager.py |   11 -----------
     2 files changed, 7 insertions(+), 20 deletions(-)
    
    diff --git a/django/db/models/base.py b/django/db/models/base.py
    index 181d845..a881f56 100644
    a b from django.db.models.options import Options, AdminOptions  
    1515from django.db import connection, transaction
    1616from django.db.models import signals
    1717from django.db.models.loading import register_models, get_model
     18from django.db.models.manager import Manager
    1819from django.dispatch import dispatcher
    1920from django.utils.datastructures import SortedDict
    2021from django.utils.functional import curry
    class ModelBase(type):  
    6566                if not hasattr(meta, 'get_latest_by'):
    6667                    new_class._meta.get_latest_by = base_meta.get_latest_by
    6768
    68         old_default_mgr = None
    69         if getattr(new_class, '_default_manager', None):
    70             # We have a parent who set the default manager.
    71             if new_class._default_manager.model._meta.abstract:
    72                 old_default_mgr = new_class._default_manager
    73             new_class._default_manager = None
    7469        if getattr(new_class._meta, 'app_label', None) is None:
    7570            # Figure out the app_label by looking one level up.
    7671            # For 'django.contrib.sites.models', this would be 'sites'.
    class ModelBase(type):  
    106101                    new_class.add_to_class(attr_name, field)
    107102                new_class._meta.parents[base] = field
    108103            else:
    109                 # The abstract base class case.
     104                # Copy fields from the abstract base class.
    110105                names = set([f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many])
    111106                for field in base._meta.local_fields + base._meta.local_many_to_many:
    112107                    if field.name in names:
    class ModelBase(type):  
    114109                                % (field.name, name, base.__name__))
    115110                    new_class.add_to_class(field.name, copy.deepcopy(field))
    116111
     112                # Copy managers from the abstract base class.
     113                for attr, value in ((attr, getattr(base, attr)) for attr in dir(base)):
     114                    if value == getattr(new_class, attr) and isinstance(value, Manager):
     115                        new_class.add_to_class(attr, copy.copy(value))
     116
    117117        if abstract:
    118118            # Abstract base models can't be instantiated and don't appear in
    119119            # the list of models for an app. We do the final setup for them a
    class ModelBase(type):  
    122122            new_class.Meta = attr_meta
    123123            return new_class
    124124
    125         if old_default_mgr and not new_class._default_manager:
    126             new_class._default_manager = old_default_mgr._copy_to_model(new_class)
    127125        new_class._prepare()
    128126        register_models(new_class._meta.app_label, new_class)
    129127
  • django/db/models/manager.py

    diff --git a/django/db/models/manager.py b/django/db/models/manager.py
    index 3a9da34..697c0f9 100644
    a b class Manager(object):  
    3636        if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter:
    3737            model._default_manager = self
    3838
    39     def _copy_to_model(self, model):
    40         """
    41         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
    43         abstract base class).
    44         """
    45         assert issubclass(model, self.model)
    46         mgr = copy.copy(self)
    47         mgr.model = model
    48         return mgr
    49 
    5039    #######################
    5140    # PROXIES TO QUERYSET #
    5241    #######################
Back to Top