On Jan 3, 7:01 am, Russell Keith-Magee <[email protected]> wrote: > On Tue, Jan 3, 2012 at 1:55 PM, Zachary Voase <[email protected]> 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 -- 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]. 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.
