Ticket #7154: 0003-Now-all-managers-not-only-the-default-manager-gets.patch
| File 0003-Now-all-managers-not-only-the-default-manager-gets.patch, 6.6 kB (added by sebastian_noack, 6 months ago) |
|---|
-
a/django/db/models/base.py
old new 65 65 if not hasattr(meta, 'get_latest_by'): 66 66 new_class._meta.get_latest_by = base_meta.get_latest_by 67 67 68 old_default_mgr = None69 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_manager73 new_class._default_manager = None74 68 if getattr(new_class._meta, 'app_label', None) is None: 75 69 # Figure out the app_label by looking one level up. 76 70 # For 'django.contrib.sites.models', this would be 'sites'. … … 106 100 new_class.add_to_class(attr_name, field) 107 101 new_class._meta.parents[base] = field 108 102 else: 109 # The abstract base class case.103 # Copy fields from the abstract base class. 110 104 names = set([f.name for f in new_class._meta.local_fields + new_class._meta.many_to_many]) 111 105 for field in base._meta.local_fields + base._meta.local_many_to_many: 112 106 if field.name in names: … … 114 108 % (field.name, name, base.__name__)) 115 109 new_class.add_to_class(field.name, copy.deepcopy(field)) 116 110 111 # Copy managers from the base model. 112 for mgr_attr, mgr in base._meta.base_managers.iteritems(): 113 if mgr_attr in new_class.__dict__: 114 continue 115 new_class.add_to_class(mgr_attr, copy.copy(mgr)) 116 117 117 if abstract: 118 118 # Abstract base models can't be instantiated and don't appear in 119 119 # the list of models for an app. We do the final setup for them a … … 122 122 new_class.Meta = attr_meta 123 123 return new_class 124 124 125 if old_default_mgr and not new_class._default_manager:126 new_class._default_manager = old_default_mgr._copy_to_model(new_class)127 125 new_class._prepare() 128 126 register_models(new_class._meta.app_label, new_class) 129 127 -
a/django/db/models/manager.py
old new 31 31 32 32 def contribute_to_class(self, model, name): 33 33 # TODO: Use weakref because of possible memory leak / circular reference. 34 self.model = model 35 setattr(model, name, ManagerDescriptor(self)) 36 if not getattr(model, '_default_manager', None) or self.creation_counter < model._default_manager.creation_counter: 37 model._default_manager = self 38 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 34 if not model._meta.abstract: 35 self.model = model 36 setattr(model, name, ManagerDescriptor(self)) 37 if not getattr(model, '_default_manager', None) or self.creation_counter == model._default_manager.creation_counter: 38 model._default_manager = self 39 model._meta.base_managers[name] = self 49 40 50 41 ####################### 51 42 # PROXIES TO QUERYSET # -
a/django/db/models/options.py
old new 44 44 self.one_to_one_field = None 45 45 self.abstract = False 46 46 self.parents = SortedDict() 47 self.base_managers = SortedDict() 47 48 48 49 def contribute_to_class(self, cls, name): 49 50 cls._meta = self -
a/tests/modeltests/model_inheritance/models.py
old new 18 18 # Abstract base classes 19 19 # 20 20 21 class AdultManager(models.Manager): 22 def get_query_set(self): 23 return super(AdultManager, self).get_query_set().filter(age__gte=18) 24 25 class Adult21Manager(models.Manager): 26 def get_query_set(self): 27 return super(Adult21Manager, self).get_query_set().filter(age__gte=21) 28 21 29 class CommonInfo(models.Model): 22 30 name = models.CharField(max_length=50) 23 31 age = models.PositiveIntegerField() 24 32 33 objects = models.Manager() 34 adults = AdultManager() 35 25 36 class Meta: 26 37 abstract = True 27 38 ordering = ['name'] … … 30 41 return u'%s %s' % (self.__class__.__name__, self.name) 31 42 32 43 class Worker(CommonInfo): 44 adults = Adult21Manager() 45 33 46 job = models.CharField(max_length=50) 34 47 35 48 class Student(CommonInfo): … … 102 115 103 116 >>> w = Worker(name='Fred', age=35, job='Quarry worker') 104 117 >>> w.save() 105 >>> w2 = Worker(name='Barney', age= 34, job='Quarry worker')118 >>> w2 = Worker(name='Barney', age=20, job='Quarry worker') 106 119 >>> w2.save() 107 120 >>> s = Student(name='Pebbles', age=5, school_class='1B') 108 121 >>> s.save() … … 121 134 >>> Student._meta.ordering 122 135 [] 123 136 137 # The children inherit the custom managers from their parents, but children can 138 # still override it. 139 >>> Student(name='Bill', age=18, school_class='11A').save() 140 >>> Student.adults.all() 141 [<Student: Student Bill>] 142 143 >>> Worker.adults.all() 144 [<Worker: Worker Fred>] 145 124 146 # However, the CommonInfo class cannot be used as a normal model (it doesn't 125 147 # exist as a model). 126 148 >>> CommonInfo.objects.all()
