Ticket #20625 deals with the problem of writing custom QuerySet methods.
The problem is that one needs to write some boilerplate code to have
methods available on both the Manager and the QuerySet. The ticket has a
patch for having custom QuerySet methods automatically available on the
model's Manager, too.
The reason for this post is that different ideas for implementing chainable
manager/queryset methods have been proposed multiple times. So, I want to
make sure we agree on the approach.
The API idea in #20625 is simple:
class MyQuerySet(models.QuerySet):
def published(self):
return self.filter(published_date__lte=now())
class MyModel(models.Model):
published_date = models.DateTimeField()
objects = MyQuerySet.as_manager()
The manager created by as_manager() will automatically have a published()
method available. The method is created dynamically, and is effectively
this:
def published(self, *args, **kwargs):
getattr(self.get_query_set(), 'published')(*args, **kwargs)
The pull request contains more details. Pull request is available from
https://github.com/django/django/pull/1328, ticket is
https://code.djangoproject.com/ticket/20625.
The other proposed approaches for chainable manager methods usually use
overridden __getattr__() on either manager or queryset and memoizes the
other part's class. The __getattr__ then delegates calls to the memoized
class. This approach has problems with super() calls and dynamic inspection
in pdb. Both of those should work with the proposed approach as the created
Manager class really has the methods available.
Another somewhat common idea is to make Manager a QuerySet subclass and
thus avoid this whole Manager/QuerySet split problem. I agree on this idea,
but the problem is that this seems to be really hard to do in a way that is
even remotely backwards compatible. I tried a couple of different
approaches and failed miserably. If somebody has a concrete idea of how to
do this, now is a good time to present it.
It should be noted that the proposed patch doesn't prevent making Manager a
QuerySet subclass later on.
I am planning to do a final review & commit the patch soonish (likely this
week).
- Anssi
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.