如何覆盖Django Djoser默认激活流程实现管理员审核激活用户账户
Djoser 自定义账户激活流程实现方案
完全可以覆盖Djoser的默认激活逻辑,按以下步骤实现即可:
1. 调整Djoser基础配置
先在settings.py中关闭默认的用户激活邮件发送,保留新用户默认未激活的状态:
DJOSER = { # 关闭默认发送给用户的激活邮件 'SEND_ACTIVATION_EMAIL': False, # 配置你需要的激活路由格式 'ACTIVATION_URL': 'auth/request_activation/{uid}/{token}', # 其他原有Djoser配置无需修改 }
2. 监听用户注册信号实现自定义邮件逻辑
Djoser用户注册完成后会触发user_registered信号,监听该信号即可同时发送用户通知邮件和管理员激活邮件:
首先在应用目录下新建signals.py:
from django.dispatch import receiver from djoser.signals import user_registered from django.core.mail import send_mail from djoser.utils import encode_uid from django.contrib.auth.tokens import default_token_generator @receiver(user_registered) def handle_new_user_registration(sender, user, request, **kwargs): # 生成激活所需的uid和token uid = encode_uid(user.pk) token = default_token_generator.make_token(user) activation_link = f"{request.build_absolute_uri('/')[:-1]}/auth/request_activation/{uid}/{token}" # 给用户发送审核通知邮件 send_mail( subject="账户注册提交成功", message="您的账户将在48小时内由管理员审核通过,请耐心等待。", from_email="系统发件邮箱地址", recipient_list=[user.email], fail_silently=False, ) # 给管理员发送带激活链接的审核邮件 send_mail( subject=f"新用户待审核:{user.username}", message=f"新用户注册申请,点击链接激活账户:{activation_link}", from_email="系统发件邮箱地址", recipient_list=["管理员邮箱1", "管理员邮箱2"], # 替换为实际管理员邮箱列表 fail_silently=False, )
然后在应用的apps.py中注册信号:
from django.apps import AppConfig class YourAppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = '你的应用名称' def ready(self): import 你的应用名称.signals
3. 实现管理员专属激活视图
创建仅管理员可访问的激活视图,校验uid和token有效性后完成用户激活:
from rest_framework.views import APIView from rest_framework.permissions import IsAdminUser from rest_framework.response import Response from rest_framework import status from djoser.utils import decode_uid from django.contrib.auth import get_user_model from django.contrib.auth.tokens import default_token_generator User = get_user_model() class AdminUserActivationView(APIView): # 限制仅管理员权限可访问 permission_classes = [IsAdminUser] def get(self, request, uid, token): # 校验uid有效性 try: user_id = decode_uid(uid) user = User.objects.get(pk=user_id) except (User.DoesNotExist, ValueError, TypeError, OverflowError): return Response({"detail": "无效的用户ID"}, status=status.HTTP_400_BAD_REQUEST) # 校验token有效性 if not default_token_generator.check_token(user, token): return Response({"detail": "无效或已过期的激活令牌"}, status=status.HTTP_400_BAD_REQUEST) # 激活用户 user.is_active = True user.save() return Response({"detail": "用户账户已成功激活"}, status=status.HTTP_200_OK)
4. 配置激活路由
在项目或应用的urls.py中添加对应路由:
from django.urls import path from .views import AdminUserActivationView urlpatterns = [ # 其他原有路由 path('auth/request_activation/<str:uid>/<str:token>/', AdminUserActivationView.as_view(), name='admin-activation'), ]
补充说明
- 默认激活token有效期和Django密码重置token有效期一致,默认为3天,可在settings.py中修改
PASSWORD_RESET_TIMEOUT = 172800将有效期改为48小时,和通知文案匹配 - 如需自定义邮件样式,可将
send_mail替换为带模板渲染的邮件发送逻辑 - 可在激活成功后额外添加给用户的通知邮件,告知用户账户已激活可用
内容的提问来源于stack exchange,提问作者Andrzej
相关产品推荐
相关产品推荐

