You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中筛选is_active=False且无可用密码的未激活用户

解决Django中查询未激活且无可用密码用户的问题

嘿,这个问题我之前也碰到过!Django的has_usable_password()是模型实例方法,没法直接用在QuerySet的filter()里——因为filter()是直接转换成数据库查询语句的,而方法是Python层面的逻辑。不过别担心,我们可以通过它的底层实现逻辑来模拟这个查询。

方法一:直接根据密码字段特征过滤

先搞清楚has_usable_password()的判断逻辑:当用户的password字段是'!'、None或者空字符串''时,这个方法会返回False(这也是Django调用set_unusable_password()或者创建无密码用户时的默认处理)。所以我们可以直接针对这些特征写查询:

from django.db.models import Q

# 获取未激活且无可用密码的用户
inactive_no_password_users = User.objects.filter(
    is_active=False,
    Q(password__exact='!') | Q(password__isnull=True) | Q(password__exact='')
)

方法二:用注解(annotate)标记可用状态

如果想让查询逻辑更清晰,也可以先通过annotate()给QuerySet添加一个标记字段,再过滤:

from django.db.models import BooleanField, Case, When, Value

users = User.objects.annotate(
    has_usable_pw=Case(
        When(password__exact='!', then=Value(False)),
        When(password__isnull=True, then=Value(False)),
        When(password__exact='', then=Value(False)),
        default=Value(True),
        output_field=BooleanField()
    )
).filter(is_active=False, has_usable_pw=False)

最佳实践:封装成自定义Manager方法

如果这个查询你会经常用到,建议把它封装到自定义的UserManager里,这样调用起来更简洁:

from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db.models import Q

class UserManager(BaseUserManager):
    # 保留默认的create_user、create_superuser等方法
    def create_user(self, username, email=None, password=None, **extra_fields):
        # 你的实现...
        pass

    # 添加自定义查询方法
    def get_inactive_no_password_users(self):
        return self.filter(
            is_active=False,
            Q(password__exact='!') | Q(password__isnull=True) | Q(password__exact='')
        )

class User(AbstractUser):
    # 指定自定义Manager
    objects = UserManager()

之后调用的时候就可以直接写:

inactive_users = User.objects.get_inactive_no_password_users()

这样不管是代码可读性还是复用性都更好~

内容的提问来源于stack exchange,提问作者Balakrishnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:42:08