=== modified file 'django/db/models/fields/related.py'
|
|
|
194 | 194 | # multiple "remote" values and have a ForeignKey pointed at them by |
195 | 195 | # some other model. In the example "poll.choice_set", the choice_set |
196 | 196 | # attribute is a ForeignRelatedObjectsDescriptor instance. |
197 | | def __init__(self, related): |
| 197 | def __init__(self, related, manager=None): |
198 | 198 | self.related = related # RelatedObject instance |
| 199 | self.manager = manager |
199 | 200 | |
200 | 201 | def __get__(self, instance, instance_type=None): |
201 | 202 | if instance is None: |
… |
… |
|
206 | 207 | |
207 | 208 | # Dynamically create a class that subclasses the related |
208 | 209 | # model's default manager. |
209 | | superclass = self.related.model._default_manager.__class__ |
| 210 | if self.manager == None: |
| 211 | superclass = self.related.model._default_manager.__class__ |
| 212 | else: |
| 213 | superclass = self.manager.__class__ |
210 | 214 | |
211 | 215 | class RelatedManager(superclass): |
212 | 216 | def get_query_set(self): |
… |
… |
|
388 | 392 | # some other model (rather than having a ManyToManyField themselves). |
389 | 393 | # In the example "publication.article_set", the article_set attribute is a |
390 | 394 | # ManyRelatedObjectsDescriptor instance. |
391 | | def __init__(self, related): |
| 395 | def __init__(self, related, manager=None): |
392 | 396 | self.related = related # RelatedObject instance |
393 | 397 | |
394 | 398 | def __get__(self, instance, instance_type=None): |
395 | 399 | if instance is None: |
396 | 400 | raise AttributeError, "Manager must be accessed via instance" |
397 | 401 | |
398 | 402 | # Dynamically create a class that subclasses the related |
399 | 403 | # model's default manager. |
| 404 | |
| 405 | if self.manager == None: |
| 406 | superclass = self.related.model._default_manager.__class__ |
| 407 | else: |
| 408 | superclass = self.manager.__class__ |
| 409 | |
400 | 410 | rel_model = self.related.model |
401 | | superclass = rel_model._default_manager.__class__ |
402 | 411 | RelatedManager = create_many_related_manager(superclass) |
403 | 412 | |
404 | 413 | qn = backend.quote_name |
… |
… |
|
550 | 558 | setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self)) |
551 | 559 | |
552 | 560 | def contribute_to_related_class(self, cls, related): |
553 | | setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related)) |
| 561 | related_accessor_name = related.get_accessor_name() |
| 562 | remote_accessors = related.get_remote_accessors() |
| 563 | |
| 564 | setattr(cls, related_accessor_name, ForeignRelatedObjectsDescriptor(related)) |
| 565 | |
| 566 | # Adding accessors with different managers |
| 567 | for racc in remote_accessors: |
| 568 | setattr(cls, "%s__%s" % (related_accessor_name, racc[0]), ForeignRelatedObjectsDescriptor(related, racc[1])) |
554 | 569 | |
555 | 570 | def formfield(self, **kwargs): |
556 | 571 | defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.all()} |
… |
… |
|
723 | 738 | # m2m relations to self do not have a ManyRelatedObjectsDescriptor, |
724 | 739 | # as it would be redundant - unless the field is non-symmetrical. |
725 | 740 | if related.model != related.parent_model or not self.rel.symmetrical: |
726 | | # Add the descriptor for the m2m relation |
727 | | setattr(cls, related.get_accessor_name(), ManyRelatedObjectsDescriptor(related)) |
| 741 | related_accessor_name = related.get_accessor_name() |
| 742 | remote_accessors = related.get_remote_accessors() |
| 743 | |
| 744 | # Add the descriptor for the m2m relation, using the default manager |
| 745 | # AND keeping backwards compatibility |
| 746 | setattr(cls, related_accessor_name, ManyRelatedObjectsDescriptor(related)) |
| 747 | |
| 748 | # Addin accessors with different managers |
| 749 | for racc in remote_accessors: |
| 750 | setattr(cls, "%s__%s" % (related_accessor_name, racc[0]), ManyRelatedObjectsDescriptor(related, racc[1])) |
728 | 751 | |
729 | 752 | # Set up the accessors for the column names on the m2m table |
730 | 753 | self.m2m_column_name = curry(self._get_m2m_column_name, related) |
=== modified file 'django/db/models/related.py'
|
|
|
19 | 19 | self.name = '%s:%s' % (self.opts.app_label, self.opts.module_name) |
20 | 20 | self.var_name = self.opts.object_name.lower() |
21 | 21 | |
| 22 | def get_remote_accessors(self): |
| 23 | d = [] |
| 24 | from django.db.models.manager import ManagerDescriptor |
| 25 | for name, attr in self.model.__dict__.items(): |
| 26 | if isinstance(attr, ManagerDescriptor): |
| 27 | d.append((name, attr.manager)) |
| 28 | return d |
| 29 | |
22 | 30 | def flatten_data(self, follow, obj=None): |
23 | 31 | new_data = {} |
24 | 32 | rel_instances = self.get_list(obj) |