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

如何在Django的UserCreationForm中设置is_active=False实现邮箱验证?

如何在Django注册时将用户is_active设为False并实现邮箱验证?

我来帮你搞定这个需求!默认的UserCreationForm创建用户时确实会把is_active设为True,我们只需要自定义表单覆盖这个行为,再配合邮箱验证逻辑就能实现你的目标。下面是一步步的实现方案:

1. 自定义用户注册表单

首先,我们需要继承UserCreationForm,重写它的save方法,把创建的用户is_active设为False。另外,默认的表单没有邮箱字段,我们也需要加上(毕竟要发验证邮件):

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms

class CustomUserCreationForm(UserCreationForm):
    # 添加必填的邮箱字段
    email = forms.EmailField(required=True, help_text="请输入有效的邮箱地址,用于接收验证邮件")

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

    def save(self, commit=True):
        # 先不提交到数据库,拿到用户实例
        user = super().save(commit=False)
        # 核心:把is_active设为False
        user.is_active = False
        # 保存用户输入的邮箱
        user.email = self.cleaned_data['email']
        
        if commit:
            user.save()
        return user

2. 创建邮箱验证模型(存储验证码/链接)

为了追踪用户的验证状态,我们需要一个模型来存储验证token和关联的用户,还可以设置过期时间提升安全性:

from django.db import models
from django.contrib.auth.models import User
import uuid
from django.utils import timezone
from datetime import timedelta

class EmailVerification(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='verification')
    # 用UUID生成唯一验证token
    token = models.UUIDField(default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(auto_now_add=True)
    # 设置24小时过期
    expires_at = models.DateTimeField(default=lambda: timezone.now() + timedelta(hours=24))

    def is_expired(self):
        return timezone.now() > self.expires_at

3. 编写注册视图:处理表单+发送验证邮件

在注册视图里,我们处理表单提交,创建未激活的用户,生成验证token,然后发送包含验证链接的邮件:

from django.shortcuts import render, redirect
from django.core.mail import send_mail
from django.contrib import messages
from .forms import CustomUserCreationForm
from .models import EmailVerification

def register(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            # 创建未激活的用户
            user = form.save()
            # 生成验证记录
            EmailVerification.objects.create(user=user)
            # 构建验证链接
            verification_url = f"{request.scheme}://{request.get_host()}/verify/{user.verification.token}/"
            # 发送验证邮件
            send_mail(
                subject='完成你的账号注册验证',
                message=f"点击下面的链接激活你的账号:\n{verification_url}\n链接24小时内有效",
                from_email='你的邮箱地址@example.com',
                recipient_list=[user.email],
                fail_silently=False,
            )
            messages.success(request, '注册成功!请检查你的邮箱,点击验证链接激活账号')
            return redirect('login') # 跳转到登录页面
    else:
        form = CustomUserCreationForm()
    return render(request, 'registration/register.html', {'form': form})

4. 编写验证视图:激活用户

接下来写处理验证链接的视图,验证token的有效性,然后把用户的is_active设为True:

from django.shortcuts import get_object_or_404, redirect
from django.contrib import messages
from .models import EmailVerification

def verify_email(request, token):
    # 根据token找到验证记录
    verification = get_object_or_404(EmailVerification, token=token)
    
    # 检查链接是否过期
    if verification.is_expired():
        messages.error(request, '验证链接已过期,请重新注册')
        verification.delete()
        return redirect('register')
    
    # 激活用户
    user = verification.user
    user.is_active = True
    user.save()
    # 验证完成后删除记录
    verification.delete()
    
    messages.success(request, '邮箱验证成功!现在可以登录你的账号了')
    return redirect('login')

5. 配置URL路由

最后,把注册和验证的视图添加到URL配置里:

from django.urls import path
from . import views

urlpatterns = [
    path('register/', views.register, name='register'),
    path('verify/<uuid:token>/', views.verify_email, name='verify_email'),
    # 其他路由...
]

额外注意事项

  • 记得在settings.py里配置好邮件发送参数,比如SMTP服务器信息,否则邮件发不出去:
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_HOST = 'smtp.example.com' # 比如smtp.gmail.com
    EMAIL_PORT = 587
    EMAIL_USE_TLS = True
    EMAIL_HOST_USER = '你的邮箱账号'
    EMAIL_HOST_PASSWORD = '你的邮箱密码/授权码'
    
  • 如果你用的是自定义用户模型,只需要把代码里的User换成你的自定义模型类即可,表单和模型关联也要对应调整。
  • 可以给验证逻辑添加更多安全校验,比如检查用户是否已经被激活,避免重复验证。

内容的提问来源于stack exchange,提问作者Md. Mizanur Rahman Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:47:05