Search code examples
djangodjango-managers

django, difference between _base_manager and objects


django internal code uses _base_manager instead of objects

There is also _default_manager

I'm more accustomed to using objects

What's the difference?


Solution

  • The difference between 'objects' and '_base_manager' is that you can replace 'objects' with custom manager, but '_base_manager' will be the default django.db.models.Manager instance anyway. In general, you should'n be using '_base_manager'. Sometimes Django itself needs to use '_base_manager' to be sure of it's behavior.

    from django.db import models
    
    
    class CommentManager(models.Manager):
        pass
    
    
    class Comment(models.Model):
        ...
        objects = CommentManager()
    
    print(type(Comment.objects)) #<class 'main.models.CommentManager'>
    print(type(Comment._default_manager)) #<class 'main.models.CommentManager'>
    print(type(Comment._base_manager)) #<class 'django.db.models.manager.Manager'>
    

    To explain '_default_manager' I'll give one more simple example:

    class Comment(models.Model):
        ...
        custom_objects = CommentManager()
    
    print(type(Comment._default_manager)) #<class 'main.models.CommentManager'>
    print(type(Comment._base_manager)) #<class 'django.db.models.manager.Manager'>
    print(type(Comment.objects)) #AttributeError: type object 'Comment' has no attribute 'objects'
    

    So, is you set custom manager to model, it won't have 'objects' attribute, but it still will have '_default_manager'(your custom manager instance) and '_base_manager' - django.db.models.Manager instance.

    Also be aware that there's a bug in Django source code related to managers according to my ticket: https://code.djangoproject.com/ticket/25897 I provided the patch to fix it, but it hasn't been applied yet.