I replied to the ticket, but I'll mention it here as well. django-model-utils has an implementation of something that achieves the same result. It was originally from http://paulm.us/post/3717466639/passthroughmanager-for-django and has since been added to https://github.com/carljm/django-model-utils
On Tuesday, January 3, 2012 at 5:18 AM, Zachary Voase wrote: > On Jan 3, 7:01 am, Russell Keith-Magee <[email protected] > (http://keith-magee.com)> > wrote: > > On Tue, Jan 3, 2012 at 1:55 PM, Zachary Voase <[email protected] > > (http://gmail.com)> wrote: > > > At the moment it's very easy to add methods to individual models, just > > > by putting a method on the model class itself which accepts 'self'. > > > However, defining business logic on collections of records is > > > currently pretty complicated — you have to create at least a custom > > > Manager subclass, and if you want to chain those methods together > > > you'll need a QuerySet subclass. An example of the desired behaviour, > > > and the steps required for it, is shown in [1]. > > > > > > > > > > I originally created django-qmixin [2] to tackle this problem; you can > > > define methods which will be present on the manager and all querysets > > > produced therefrom, including on relations. However, the django-qmixin > > > approach of creating a mixin and then including that on the Manager > > > class object doesn't really gel with the rest of Django core. I've > > > worked out two approaches which are easier for novices to understand, > > > and match the idioms of the rest of Django. They both involve adding a > > > @models.querymethod decorator, which would be applied to methods which > > > operate on collections of records (i.e. querysets). It's an analog to > > > Python's @classmethod. > > > > > > > > > > The first approach [3] involves adding these querymethods to the model > > > class itself; the second [4] adds them to a manager subclass (but > > > without the trouble of the QuerySet subclass). I prefer the former, > > > for simplicity, but you may believe otherwise. > > > > > > > > > I think I'm in the "otherwise" camp -- primarily for reasons of namespacing. > > > > The QuerySet and the Manager are different classes, but they effective > > share a namespace. It's good practice (and a practice that your > > example demonstrates) for the Manager and the QuerySet to use the same > > names for their methods; it makes a certain amount of sense to me that > > there should be handy shortcut to automagically perform this > > duplication. > > > > However, the same isn't true of the Model and the QuerySet. The API > > for a Model and the API for a QuerySet are quite different -- and > > intentionally so. Sticking QuerySet methods on a Model in order to > > avoid a couple of lines of manager definition and registration seems a > > little odd to me, in an "explicit is better that implicit" kinda way. > > For my money, it's better to be explicit that you're defining a custom > > manager. > > > > In practical terms, there are two ways that this could manifest. > > > > Firstly, if there is a namespace collision -- i.e., if you want > > MyObject.objects.foo() and myinstance.foo() do different things. I > > can't think of an obvious practical example off the top of my head, > > but anything where the verb and collective noun aren't distinguishable > > would be a candidate for a collision. > > > > Secondly, if you have more than one manager, you may want a method on > > one manager, but not the other. For this case, we'd need to have the > > Manager-based shortcut anyway, or tell people that if you have > > multiple managers, you need to do the full-manual queryset definion. > > > > > I'm working on a proof-of-concept implementation, but I feel it's more > > > important to agree on the interface and rationale beforehand. Any > > > thoughts? > > > > > > > > > As I mentioned to you in person at DC.eu (http://DC.eu) -- details > > notwithstanding, > > I'm +1 to this idea. QuerySet+Manager is a common pattern, and it > > deserves to have a simplification in Django's core. > > > > > Here's an example which proves your point: an `as_json()` method which > serializes a model to a JSON-compatible dictionary. You'd probably > want that on both the model instance and the QuerySet. The model > instance one would just pluck out attributes, whereas the QuerySet one > might use `values()` instead. > > I just created a ticket for this feature proposal: > https://code.djangoproject.com/ticket/17494 > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to [email protected] > (mailto:[email protected]). > To unsubscribe from this group, send email to > [email protected] > (mailto:[email protected]). > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
