覆盖Django用户管理器以仅返回查询中的活动用户

时间:2013-01-02 22:56:23

标签: python django django-models django-queryset

需要一种方法来调用User.objects.filter/get,只返回is_active设置为True的用户对象。

我尝试定义一个自定义管理器并将其修补到User模型上,如下所示:

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()

但是,当我尝试调用User.objects.get()时,我得到:
AttributeError: 'NoneType' object has no attribute '_meta'

在我进一步讨论之前,我想说我知道像这样的猴子修补在可维护性方面是非常糟糕的 - 这将标记为稍后重新审视,但是现在我们需要快速解决方案

这是完整的堆栈跟踪,如果有人也想要这样:

  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'

2 个答案:

答案 0 :(得分:1)

是否需要将过滤器应用于用户模型?你为什么不尝试对这个模型进行子类化?并为这个模型编写一个管理器。

class CustomUserManager(UserManager):

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


class MyUser(User):
    objects = CustomUserManager()

# get an active user which username is 'foo'
MyUser.objects.get(username='foo')

或使用proxy model

答案 1 :(得分:0)

this post中找到答案。由于他的问题具体而且我的问题很普遍,我不认为它们是重复的,但他的问题的答案也回答了我的问题。