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.

Reply via email to