Default manager

95 views
Skip to first unread message

Alex Rades

unread,
Dec 15, 2008, 5:51:48 AM12/15/08
to django-d...@googlegroups.com
Hi,
my understanding about custom managers is that if you want to define a
custom manager, you also HAVE to remember to define the "objects"
manager first, otherwise some parts of django (eg. admin) will not
work.

I find this suboptimal.

I think that "objects" should always be the default manager, always
present and working. If you want to define a new one, this should not
interfere with "objects" being present and working. Of course you can
overwrite "objects" if you need to (eg. when you want to customize the
initial queryset).

The downside of this solution is that you cannot use a field named
"objects", but this is a feature for me, as it improves readability.

What do you think?

mrts

unread,
Dec 15, 2008, 7:55:48 AM12/15/08
to Django developers

Karen Tracey

unread,
Dec 15, 2008, 9:12:25 AM12/15/08
to django-d...@googlegroups.com
On Mon, Dec 15, 2008 at 5:51 AM, Alex Rades <aler...@gmail.com> wrote:

Hi,
my understanding about custom managers is that if you want to define a
custom manager, you also HAVE to remember to define the "objects"
manager first, otherwise some parts of django (eg. admin) will not
work.

What does "will not work" mean, exactly?  I recall looking at this in response to a ticket at one point, and the admin behavior I observed was internally consistent and made logical sense to me (if I recall correctly, if something was excluded in the default manager, it didn't show up in the change list, and an attempt to get to its individual edit page by manually constructing the appropriate url returned a 404).  I can't tell from what you've said if this behavior constitutes what you mean by "will not work", if this behavior has changed, or if there is something else about admin's behavior in this situation that you are objecting to.


I find this suboptimal.

I think that "objects" should always be the default manager, always
present and working. If you want to define a new one, this should not
interfere with "objects" being present and working. Of course you can
overwrite "objects" if you need to (eg. when you want to customize the
initial queryset).

The downside of this solution is that you cannot use a field named
"objects", but this is a feature for me, as it improves readability.

What do you think?


I'd think it unlikely at this point a change would be made that would prohibit having a field named 'objects'; the time for such a backwards-incompatible change was pre 1.0, if ever. If no one pre-1.0 found the exisitng behavior troublesome enough to make a convincing argument that such a change was needed I'm doubtful a case can be made now.  Also, due to the fact that you haven't defined "broken" I'm unconvinced that whatever troublesome admin behavior is involved here couldn't be fixed with some other, backwards-compatible, change.  So if you really want to pursue this you need to lay out exactly what admin behavior causes problems in this area, and show how it couldn't be fixed in some other way than introducing such a backwards-incompatible change.

Karen

Alex Rades

unread,
Dec 15, 2008, 11:33:45 AM12/15/08
to django-d...@googlegroups.com
On Mon, Dec 15, 2008 at 3:12 PM, Karen Tracey <kmtr...@gmail.com> wrote:
> On Mon, Dec 15, 2008 at 5:51 AM, Alex Rades <aler...@gmail.com> wrote:
>>
>> Hi,
>> my understanding about custom managers is that if you want to define a
>> custom manager, you also HAVE to remember to define the "objects"
>> manager first, otherwise some parts of django (eg. admin) will not
>> work.
>
> What does "will not work" mean, exactly? I recall looking at this in
> response to a ticket at one point, and the admin behavior I observed was
> internally consistent and made logical sense to me (if I recall correctly,
> if something was excluded in the default manager, it didn't show up in the
> change list, and an attempt to get to its individual edit page by manually
> constructing the appropriate url returned a 404). I can't tell from what
> you've said if this behavior constitutes what you mean by "will not work",
> if this behavior has changed, or if there is something else about admin's
> behavior in this situation that you are objecting to.

With "not work" I mean nothing is displayed in the admin listing pages
(UNLESS you remember to define the "objects" manager. )

Lets take a closer look... if you write something like:

class DummyManager(models.Manager):
def get_query_set(self):
return EmptyQuerySet()

class MyModel(models.Model):
[...]
dummies = DummyManager()

"dummies" now is the default manager, and the admin listing page is
empty. This is fine since the default manager returns an empty qset.
This is also fine since the admin uses MyModel._default_manager to
access it.

So, yes the admin behaviour complies with the documentation. While its
behaviour is correct, I think the general idea behind the declaraction
of managers it is counterintuitive. Why? Imagine we want to _add_ a
manager to our model which does some kind of filtering. If you want to
retain the ability to access ALL of your MyModel objects, you are
forced to write an additional manager. The previous example becomes:

class MyModel(models.Model):
[...]
amanager = models.Manager()
dummies = DummyManager()

I think that a general manager, which returns all the model
instancies, should be always present and accessibile. Of course if you
really need, you canoverwrite it. But I think that having to add 2
managers when you just need to add one is wrong.
Another +1 for this is that if you want to access the default manager,
at the moment you have to use

MyModel._default_manager

Which relies on an implementation detail and looks very bad.

So, my proposal is to make the "objects" manager always present and
accessible, and remove the _default_manager stuff. If you want to
change the default manager, just override "objects". If you want to
access the default manager, just access "objects".

>
>>
>> I find this suboptimal.
>>
>> I think that "objects" should always be the default manager, always
>> present and working. If you want to define a new one, this should not
>> interfere with "objects" being present and working. Of course you can
>> overwrite "objects" if you need to (eg. when you want to customize the
>> initial queryset).
>>
>> The downside of this solution is that you cannot use a field named
>> "objects", but this is a feature for me, as it improves readability.
>>
>> What do you think?
>>
>
> I'd think it unlikely at this point a change would be made that would
> prohibit having a field named 'objects'; the time for such a
> backwards-incompatible change was pre 1.0, if ever. If no one pre-1.0 found
> the exisitng behavior troublesome enough to make a convincing argument that
> such a change was needed I'm doubtful a case can be made now. Also, due to
> the fact that you haven't defined "broken" I'm unconvinced that whatever
> troublesome admin behavior is involved here couldn't be fixed with some
> other, backwards-compatible, change. So if you really want to pursue this
> you need to lay out exactly what admin behavior causes problems in this
> area, and show how it couldn't be fixed in some other way than introducing
> such a backwards-incompatible change.

I've never said I'd like to see this behaviour in 1.0 :)

J. Cliff Dyer

unread,
Dec 15, 2008, 2:14:34 PM12/15/08
to django-d...@googlegroups.com

On Mon, 2008-12-15 at 09:12 -0500, Karen Tracey wrote:
> I'd think it unlikely at this point a change would be made that would
> prohibit having a field named 'objects'; the time for such a
> backwards-incompatible change was pre 1.0, if ever. If no one pre-1.0
> found the exisitng behavior troublesome enough to make a convincing
> argument that such a change was needed I'm doubtful a case can be made
> now. Also, due to the fact that you haven't defined "broken" I'm
> unconvinced that whatever troublesome admin behavior is involved here
> couldn't be fixed with some other, backwards-compatible, change. So
> if you really want to pursue this you need to lay out exactly what
> admin behavior causes problems in this area, and show how it couldn't
> be fixed in some other way than introducing such a
> backwards-incompatible change.

Agreed about the 1.0 problem, but it might make sense to have a manager
bound to objects if objects is not defined. Then objects could be used
as a field or another manager as desired, but would bind to the default
manager (wait for it)... by default. If you didn't want a manager
defined, you could set objects=None in your model.

Just a thought.

Cheers,
Cliff


Johannes Dollinger

unread,
Dec 15, 2008, 3:38:48 PM12/15/08
to django-d...@googlegroups.com
I like the `objects` convention as well as explict default manager
declarations.
I proposed both in http://groups.google.at/group/django-developers/browse_thread/thread/3e1a668ac84328b6/ce36cbe46276d807
.

Advertisement:
============
My radical "solution" is to never modify the initial QuerySet. And I
use exactly one manager per model.
The example for my "one manager should be enough for everyone"-
approach from the thread above now lives here: http://dpaste.com/hold/99386/
.

A DRYer version:
{{{
class MusicianQuerySet(PersonQuerySet):
@proxy_manager_method
def guitarists(self):
return self.filter(instrument='guitar')

class Musician(Person):
instrument = models.CharField(max_length=50)
objects = QuerySetProxyManager(MusicianQuerySet)()
}}}

So, why do you need more than one manager per model?
Or: why is Post.live.all() better than Post.objects.live()?

Martin

unread,
Dec 16, 2008, 8:37:14 AM12/16/08
to Django developers
> So, my proposal is to make the "objects" manager always present and
> accessible, and remove the _default_manager stuff. If you want to
> change the default manager, just override "objects". If you want to
> access the default manager, just access "objects".

+1

James Bennett

unread,
Dec 16, 2008, 9:44:07 AM12/16/08
to django-d...@googlegroups.com
On Mon, Dec 15, 2008 at 4:51 AM, Alex Rades <aler...@gmail.com> wrote:
> my understanding about custom managers is that if you want to define a
> custom manager, you also HAVE to remember to define the "objects"
> manager first, otherwise some parts of django (eg. admin) will not
> work.

No, if you want to have every object viewable/editable in the admin
you have to either set up a default manager which makes all objects
available, or you have to do some overriding in the ModelAdmin
subclass to make sure it gets the QuerySet you want it to get.

> I find this suboptimal.

I find it pretty logical, and I can think of plenty of cases where the
ability to prevent access to certain objects is a requirement. So I'm
very much against this proposal.


--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

Alberto Donato

unread,
Dec 16, 2008, 11:21:27 AM12/16/08
to django-d...@googlegroups.com

For this case, following the previous example, you could simply write

class MyModel(models.Model):
[...]
objects = MyManager()

where MyManager returns a filtered QuerySet. Any app accessing objects
without explicit knowing about the existence of different managers
will operate on this QuerySet.

I don't see any downside in this proposal.

James Bennett

unread,
Dec 16, 2008, 11:49:17 AM12/16/08
to django-d...@googlegroups.com
On Tue, Dec 16, 2008 at 10:21 AM, Alberto Donato
<alberto...@gmail.com> wrote:
> I don't see any downside in this proposal.

His proposal seems to center around forcibly making "objects" *always*
be a manager returning an unfiltered QuerySet, so I'm not sure where
it'd allow for that. And that's a downside (not to mention the fact
that it's really not that hard to get stuff right currently -- the
default behavior works, and if you start customizing the documentation
explains clearly what will happen and what to do).

James Richards

unread,
Dec 16, 2008, 4:10:00 PM12/16/08
to django-d...@googlegroups.com
+1!

Alex Rades

unread,
Dec 16, 2008, 5:55:52 PM12/16/08
to django-d...@googlegroups.com
On Tue, Dec 16, 2008 at 5:49 PM, James Bennett <ubern...@gmail.com> wrote:
>
> On Tue, Dec 16, 2008 at 10:21 AM, Alberto Donato
> <alberto...@gmail.com> wrote:
>> I don't see any downside in this proposal.
>
> His proposal seems to center around forcibly making "objects" *always*
> be a manager returning an unfiltered QuerySet, so I'm not sure where
> it'd allow for that. And that's a downside (not to mention the fact
> that it's really not that hard to get stuff right currently -- the
> default behavior works, and if you start customizing the documentation
> explains clearly what will happen and what to do).

Hi,
I don't want to forcibly make "objects" always be a manager returning
QuerySect. Infact with my proposal, if you want to restrict somewhat
the "objects" manager, you just override it.

Alex Rades

unread,
Dec 16, 2008, 5:58:23 PM12/16/08
to django-d...@googlegroups.com
On Tue, Dec 16, 2008 at 11:55 PM, Alex Rades <aler...@gmail.com> wrote:
> On Tue, Dec 16, 2008 at 5:49 PM, James Bennett <ubern...@gmail.com> wrote:
>>
>> On Tue, Dec 16, 2008 at 10:21 AM, Alberto Donato
>> <alberto...@gmail.com> wrote:
>>> I don't see any downside in this proposal.
>>
>> His proposal seems to center around forcibly making "objects" *always*
>> be a manager returning an unfiltered QuerySet, so I'm not sure where
>> it'd allow for that. And that's a downside (not to mention the fact
>> that it's really not that hard to get stuff right currently -- the
>> default behavior works, and if you start customizing the documentation
>> explains clearly what will happen and what to do).
>
> Hi,
> I don't want to forcibly make "objects" always be a manager returning
> QuerySect.
Sorry... better to write stuff like this when you're awake. I mean
"manager returning unfiltered QuerySet"
Reply all
Reply to author
Forward
0 new messages