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.


Reply via email to