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?
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?
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 :)
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
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()?
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."
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.
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.