Allow to change the default model manager

114 views
Skip to first unread message

Paulo Gabriel Poiati

unread,
Aug 26, 2016, 6:58:01 PM8/26/16
to Django Developers
Hello,

I’m not sure if this have been discussed here already. I didn’t find anything in Tracker.

What if we allow the change of the default manager of all models? This could be done through the settings, something like DEFAULT_MODEL_MANAGER.

Examples of use cases are:

- Change the `create` method to do a full clean before saving;
- Filter all entities with a common query like `{deleted: False}`;
- Do some logging…

Of course this can be done if all models extends a custom class (that change the default manager).

But what about changing it between environments? Like using a mock specific Manager during the tests, this could be really useful IMO.

Cheers!



--
[]'s
Paulo Poiati

Aymeric Augustin

unread,
Aug 27, 2016, 8:18:10 AM8/27/16
to django-d...@googlegroups.com
Hello,

> On 27 Aug 2016, at 00:57, Paulo Gabriel Poiati <paulog...@gmail.com> wrote:
>
> What if we allow the change of the default manager of all models?
>
> This could be done through the settings, something like DEFAULT_MODEL_MANAGER.

If you’ve been following this mailing list for some time, you may have noticed that proposals to add new settings aren’t very popular :-)

> Of course this can be done if all models extends a custom class (that change the default manager).

This is indeed the approach I would suggest. Many projects do this, typically to add created_at, updated_at, UUID, etc

> But what about changing it between environments? Like using a mock specific Manager during the tests, this could be really useful IMO.

You can do this with a custom setting. It doesn’t have to be implemented in Django. Just import dynamically your manager class:

from django.conf import settings
from django.utils.module_loading import import_string

DefaultManager = import_string(settings.DEFAULT_MODEL_MANAGER)

and apply it to your base class for your model, or anywhere else you need it:

from django.db import models

class ModelBase(models.Model):
objects = DefaultManager()

Best regards,

--
Aymeric.

Paulo Gabriel Poiati

unread,
Aug 27, 2016, 11:48:45 AM8/27/16
to django-d...@googlegroups.com
Hello Aymeric,

I think you are probably right, including it in Django itself will only benefit big projects. I mean, changing all the existing models to receive the DefaultManager is a burden depending on the project size. But we can overcome this by applying the “never extend models.Model directly” pattern.

Thank you!

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/0634F361-43D0-4996-AF1D-49C7816F5BD5%40polytechnique.org.
For more options, visit https://groups.google.com/d/optout.

Michal Petrucha

unread,
Aug 27, 2016, 12:14:23 PM8/27/16
to django-d...@googlegroups.com
On August 27, 2016 5:48:26 PM GMT+02:00, Paulo Gabriel Poiati <paulog...@gmail.com> wrote:
>Hello Aymeric,
>
>I think you are probably right, including it in Django itself will
>only benefit big projects. I mean, changing all the existing models
>to receive the DefaultManager is a burden depending on the project
>size. But we can overcome this by applying the “never extend
>models.Model directly” pattern.

Another argument against this feature would be that most Django
projects use a collection of third-party packages, or at least some
from django.contrib. Globally changing all models' default managers
wouldn't only affect your code, but also every package that's not
under your control. As long as you'd only add some logging, that might
be OK, but changing behavior in any way (like adding a default filter,
or changing the behavior of create, as you suggested in the original
post) would likely break those third-party packages with a lot of
potential for hard to find obscure issues. Unless, of course, you
explicitly whitelist only your models in that custom manager, and fall
back to the default behavior in other models, but that would rather
beat the purpose of this feature.

For customizations like this you're definitely better off opting in
with every single model (using your own base class) than changing all
models globally.

Cheers,

Michal

Paulo Gabriel Poiati

unread,
Aug 27, 2016, 1:39:54 PM8/27/16
to django-d...@googlegroups.com
Yeah, that’s a good point Michal.

--
You received this message because you are subscribed to the Google Groups "Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages