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 django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to