I would like to point out that using both a custom `Manager` *and* a custom `QuerySet` is an edge case. After all, you can already do that if you want to.
The goal is to make it painfully easy to get a `Manager` from a custom `QuerySet` and for most cases, having the factory on `Manager` instead of `QuerySet` results in a more verbose syntax and requires an unnecessary import. In any case, a factory is better than the `Manager(MyQuerySet)` syntax (may it be through __new__, self.__class__, __getattr__ or __getattribute__) because it lets us create the classes ahead of time and it works well with inheritance. -- Loic On Jul 22, 2013, at 9:44 PM, Shai Berger <[email protected]> wrote: > On Monday 22 July 2013 13:25:38 Anssi Kääriäinen wrote: >> On Monday, July 22, 2013 1:16:04 PM UTC+3, Loic Bistuer wrote: >>> On Jul 22, 2013, at 4:38 PM, Chris Wilson >>> <[email protected]<javascript:>> >>> >>> wrote: >>>> I think that's very true. How about this? >>>> >>>>> class MyQuerySet(models.QuerySet): >>>>> def published(self): >>>>> return self.filter(published_date__lte=now()) >>>>> >>>>> class MyModel(models.Model): >>>>> published_date = models.DateTimeField() >>>>> >>>>> objects = CustomManager(MyQuerySet) >>> >>> That was my original proposal; the first 20 comments on the ticket and >>> one nearly complete implementation are based on this idea. >>> >>> That approach has the downside of requiring the use of `__getattr__` or >>> `__getattribute__` which is IMO much more of a hack than a class factory, >>> especially with backward compatibility in mind. >> >> The Manager(MyQuerySet) approach might actually work with dynamically >> created methods, too. I believe __new__ can be used for this, or maybe one >> could just create a dynamic class of self.__class__ in Manager.__init__ and >> assign it back to self.__class__. If this way works it seems cleaner than >> the as_manager() way. >> > +1 -- except I would use Aymeric's syntax Manager.from_queryset(qset_class), > where from_queryset is a classmethod; this, then, also gives a very elegant > solution to manager-only methods: > > class MyQuerySet(QuerySet): > pass > > class MyManager(Manager): > def manager_only_method(self): > pass > > class MyModel(Model): > objects = MyManager.from_queryset(MyQuerySet) > > The reason I'd prefer this over playing with __new__ and __init__ is just > because it looks a lot less like black magic. Functionally, I think you can > get pretty much the same either way. -- 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.
