> Taking this approach a little further, it could also address Adrian's
> Manager __call__ problem with Jacob's Article.objects() proposal.
> Rather than exposing the manager itself, expose an interface that can
> be used as a factory for producing Query objects. Keep the Manager
> internally as a mechanism for managing database connections and SQL
> composition, but don't expose it as the Article.objects member.
> 
> On the class itself, Article.objects(), Article.values(),
> Article.in_bulk() become factory methods for producing Query objects
> which, when iterated, provide objects of the expected type (instances,
> dictionaries, etc).
> 
> filter, order_by, etc are kept as methods on a query object itself,
> rather than methods on the manager. If you want to apply a filter, use
> Article.objects().filter(headline="foo"). The metaphor here is 'make a
> basic query object, then narrow it with a filter'.
> 
> On class instances, article_obj.sites() becomes the analogous factory
> method for queries.

I've got to say, this is absolutely horrible and non-obvious. API design
should not be an exercise in how clever or confusing you should be - it
should be non-surprising. Article.objects acting as a set of Articles is
non-surprising. Article.objects.filter(whatever="fish") returning a new
filtered set is non surprising.

> This approach also simplifies one use case for multiple managers -
> pre-filtered Managers. If you need every query to have a particular
> filter pre-applied, add a class method that returns
> objects().filter(...) as required.

And this is simpler than

class Something:
   name = CharField(maxlength=100)
   objects = Manager()
   bad_objects = objects.filter(name_startswith="bad")

how? (Yes, its a contrived example.)

Reply via email to