class MembershipManager(models.Manager): def get_by_type(self, type, user=None): # figure out if we need user or not...
# then call self.get_queryset().get() pass class Membership(models.Model): user = models.ForeignKey('auth.User', related_name='memberships') m_type = models.CharField(max_length=200) objects = MembershipManager()
So... how does get_by_type know if it's being called as "user.memberships.get_by_type(foo)" or "Membership.objects.get_by_type(foo, user=bar)?" Well, I knew that related managers pre-filter on the object they're related to, so I just had to find the code that does that.
It's right here in the ForeignRelatedObjectsDescriptor class. The interesting bit is:
def related_manager_cls(self): # Dynamically create a class that subclasses the related model's default # manager. superclass = self.related.model._default_manager.__class__ rel_field = self.related.field rel_model = self.related.model class RelatedManager(superclass): def __init__(self, instance): super(RelatedManager, self).__init__() self.instance = instance self.core_filters= {'%s__exact' % rel_field.name: instance} self.model = rel_model
This is a class factory that, in this case, subclasses MembershipManager when creating the attribute user.memberships (actually, that's not quite true. user.memberships is actually the ForeignRelatedObjectsDescriptor which hands out this dynamically created, and unnamed, subclass of MembershipManager. The descriptor is used as a proxy so that User.memberships doesn't return anything that actually is a related manager because it would be misleading at best.)
So, long story short, if self.instance exists when `get_by_type` is called, we're in a related object subclass and you can check if self.instance is a User object, in which case you can then allow the caller to skip the user keyword argument.
This is probably documented somewhere on the Django site, but I couldn't find it easily.
“Benjamin Briel Lee was very professional at all times, keeping me aware of everything that was happening, If I had any questions he was always available to answer. This was my first home purchase, I didn’t know much about the loan process, he made it very easy to understand the things I had questions about. I really enjoyed working with him.”
ReplyDeleteHe's a loan officer working with a group of investor's who are willing to fund any project or loan you any amount with a very low interest.Contact Benjamin Briel Lee E-Mail: 247officedept@gmail.com Whats-App Number: +1-989-394-3740.