pythondjangodjango-modelsdjango-queryset

Override Django User Manager to only return active users in queries


Need a way for calls to User.objects.filter/get to only return User objects with is_active set to True.

I tried to define a custom Manager and monkey patch it onto the User model, like this:

class CustomUserManager(UserManager):

    def get_query_set(self):
        return super(CustomUserManager, self).get_query_set().
          filter(is_active=True)

User.objects = CustomUserManager()
User.objects_all = UserManager()

But, when I try to make a call to User.objects.get(), I get:
AttributeError: 'NoneType' object has no attribute '_meta'

Before I go any further, I'd want to say that I know that monkey patching like this is very bad form in terms of maintainability -- this will be marked to be revisited later, but right now we need a quick solution.

Here's the full stack trace, if anyone wants that as well:

  File "<console>", line 1, in <module>
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/manager.py", line 131, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/query.py", line 358, in get
    clone = self.filter(*args, **kwargs)
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/query.py", line 621, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/query.py", line 639, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1250, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1114, in add_filter
    opts = self.get_meta()
  File "/Users/zarathustra/Virtual_Envs/fierce-spring-7383/venv/lib/python2.7/site-packages/django/db/models/sql/query.py", line 233, in get_meta
    return self.model._meta
AttributeError: 'NoneType' object has no attribute '_meta'

Solution

  • If it's not a requirement to apply the filter to the User model, you can try to customize the objects manager like the following:

    class CustomUserManager(UserManager):
    
        def get_queryset(self):
            return super(CustomUserManager, self).get_queryset().filter(is_active=True)
    
          
    class MyUser(User):
        objects = CustomUserManager()
    
    # get an active user which username is 'foo'
    MyUser.objects.get(username='foo')
    

    or use a proxy model