Opened 4 years ago

Last modified 13 months ago

#19040 new New feature

Allow declaring a model Manager class inside the model class

Reported by: rosensteinniklas@… Owned by:
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords: model manager
Cc: jelena.kutalovskaja@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


It is not possible to have a models' Manager-class defined on the models' class-level this way:

class Post(models.Model):
    title = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50, blank=True, unique=True)
    body = models.TextField(blank=True)
    pub_date = models.DateTimeField(blank=True)
    mod_date = models.DateTimeField(blank=True)
    tags = models.ManyToManyField(Tag)

    class Meta:
        ordering = ['pub_date'] # Newest first

    class Manager(models.Manager):

        def by_slug(self, slug):
            slug = slug.strip().lower()
            return self.get(slug=slug)

    objects = Manager()

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        self.slug = self.slug or generate_slug(self.title)
        self.pub_date = self.pub_date or
        self.mod_date =
        return super(Post, self).save(*args, **kwargs)

I got the following error:

Traceback (most recent call last):
  File "C:\Users\niklas\Desktop\blog_project\", line 10, in <module>
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\core\management\", line 443, in execute_from_command_line
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\core\management\", line 382, in execute
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\core\management\", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\core\management\", line 231, in execute
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\core\management\", line 266, in validate
    num_errors = get_validation_errors(s, app)
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\core\management\", line 30, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\db\models\", line 158, in get_app_errors
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\db\models\", line 64, in _populate
    self.load_app(app_name, True)
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\db\models\", line 88, in load_app
    models = import_module('.models', app_name)
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\utils\", line 35, in import_module
  File "C:\Users\niklas\Desktop\blog_project\blog\", line 48, in <module>
    class Post(models.Model):
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\db\models\", line 99, in __new__
    new_class.add_to_class(obj_name, obj)
  File "C:\Python27\lib\site-packages\django-1.4.1-py2.7.egg\django\db\models\", line 219, in add_to_class
    value.contribute_to_class(cls, name)
TypeError: Error when calling the metaclass bases
    unbound method contribute_to_class() must be called with Manager instance as first argument (got ModelBase instance instead)

Change History (8)

comment:1 Changed 4 years ago by charettes

  • Cc charette.s@… added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed
  • Version changed from 1.4 to master

Is there a reason you why can't define the Manager subclass out of the Model subclass definition?

Unless you can provide a good reason to so, I'm inclined toward marking this ticket as wontfix since fixing it implicates adding some method inspection in ModelBase.add_to_class. Marking as DDN to get someone else review.

IMO it's not worth the overhead.

comment:2 Changed 4 years ago by rosensteinniklas@…

I'd prefer this structure. If the manager was usable with other models as well, I'd admit putting it outside of and give it a meaningful name. But if it is only used for one model, putting it directly into the class makes the most sense to me.

Why should I have


when it would also be possible to have the following:


(haven't yet tried it with the django.contrib.admin.ModelAdmin class)

comment:3 Changed 4 years ago by Amirouche <amirouche.boubekki@…>

It's a nice feature to have, it also allow to override the model Manager and Admin objects against Post.Manager and Post.Admin instead of PostAdmin and PostManager which is my style of programming but might not be yours.

The overhead is at instanciation time.

The real question is whether it is good pratice to somewhat couple the model with its manager and admin in regard of separation of concerns.

The OP is right «But if it is only used for one model, putting it directly into the class makes the most sense to me.»

comment:4 Changed 4 years ago by aaugustin

If there's a simple patch to allow this, it's worth considering.

comment:5 Changed 3 years ago by aaugustin

  • Triage Stage changed from Design decision needed to Accepted

comment:6 Changed 2 years ago by jelenak

  • Cc jelena.kutalovskaja@… added
  • Owner changed from nobody to jelenak
  • Status changed from new to assigned

comment:7 Changed 13 months ago by timgraham

  • Owner jelenak deleted
  • Status changed from assigned to new
  • Summary changed from models.Manager on class-level of models.Model does not work to Allow declaring a model Manager class inside the model class
  • Type changed from Bug to New feature

comment:8 Changed 13 months ago by charettes

  • Cc charette.s@… removed
Note: See TracTickets for help on using tickets.
Back to Top