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 <s...@platonix.com> 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
>>> <ch...@aptivate.org<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 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