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

如何在Django中使用不同数据表实现身份验证?

Django 多表身份验证实现(对应Laravel Auth Guard)

核心业务逻辑

  1. 为普通用户和管理员分别定义独立的自定义用户模型,继承Django认证体系基类,保留密码加密、权限管理等原生功能。
  2. 编写对应模型的认证后端,让Django能针对不同模型执行身份校验。
  3. 为两类用户分别编写登录视图,指定对应的认证后端完成登录流程。
  4. 配置项目支持多认证后端,实现不同入口的身份验证分流。

代码实现步骤

1. 定义自定义用户模型(models.py)

分别创建User(普通用户)和Admin(管理员)模型,均继承AbstractBaseUser和PermissionsMixin,实现必要字段和管理器:

普通用户模型

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('必须填写邮箱')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('超级用户必须设置is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('超级用户必须设置is_superuser=True')

        return self.create_user(email, password, **extra_fields)

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

管理员模型

class AdminManager(BaseUserManager):
    def create_admin(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('必须填写邮箱')
        email = self.normalize_email(email)
        admin = self.model(email=email, **extra_fields)
        admin.set_password(password)
        admin.save(using=self._db)
        return admin

    def create_superadmin(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('超级管理员必须设置is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('超级管理员必须设置is_superuser=True')

        return self.create_admin(email, password, **extra_fields)

class Admin(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=True)  # 管理员默认具备后台访问权限

    objects = AdminManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

2. 自定义认证后端(backends.py)

创建两个认证后端,分别对应Admin和User模型,实现authenticate和get_user方法:

from django.contrib.auth.backends import ModelBackend
from .models import Admin, User

class AdminBackend(ModelBackend):
    def authenticate(self, request, email=None, password=None, **kwargs):
        try:
            admin = Admin.objects.get(email=email)
            if admin.check_password(password) and admin.is_active:
                return admin
        except Admin.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return Admin.objects.get(pk=user_id)
        except Admin.DoesNotExist:
            return None

class UserBackend(ModelBackend):
    def authenticate(self, request, email=None, password=None, **kwargs):
        try:
            user = User.objects.get(email=email)
            if user.check_password(password) and user.is_active:
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

3. 配置认证后端(settings.py)

在项目配置中添加自定义的认证后端:

AUTHENTICATION_BACKENDS = [
    'your_app_name.backends.AdminBackend',
    'your_app_name.backends.UserBackend',
    # 若需保留默认auth_user表的认证,可取消下方注释
    # 'django.contrib.auth.backends.ModelBackend',
]

4. 编写登录视图(views.py)

为管理员和普通用户分别编写登录视图,指定对应的认证后端完成校验:

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.contrib import messages

def admin_login(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
        # 指定使用管理员认证后端
        admin = authenticate(request, email=email, password=password, backend='your_app_name.backends.AdminBackend')
        if admin:
            login(request, admin)
            return redirect('admin_dashboard')  # 跳转到管理员后台页面
        messages.error(request, '邮箱或密码错误')
    return render(request, 'admin_login.html')

def user_login(request):
    if request.method == 'POST':
        email = request.POST['email']
        password = request.POST['password']
        # 指定使用普通用户认证后端
        user = authenticate(request, email=email, password=password, backend='your_app_name.backends.UserBackend')
        if user:
            login(request, user)
            return redirect('user_dashboard')  # 跳转到用户前台页面
        messages.error(request, '邮箱或密码错误')
    return render(request, 'user_login.html')

5. 配置路由(urls.py)

添加登录路由:

from django.urls import path
from . import views

urlpatterns = [
    path('admin/login/', views.admin_login, name='admin_login'),
    path('user/login/', views.user_login, name='user_login'),
    # 管理员后台、用户前台路由示例
    path('admin/dashboard/', views.admin_dashboard, name='admin_dashboard'),
    path('user/dashboard/', views.user_dashboard, name='user_dashboard'),
]

6. 权限控制示例

如果需要限制页面访问权限,可使用user_passes_test装饰器校验用户类型:

from django.contrib.auth.decorators import user_passes_test

def is_admin(user):
    return isinstance(user, Admin)

@user_passes_test(is_admin)
def admin_dashboard(request):
    return render(request, 'admin_dashboard.html')

注意事项

  • 完成模型定义后,需执行数据库迁移:python manage.py makemigrations 和 python manage.py migrate
  • 自行编写登录模板(admin_login.html、user_login.html),确保表单提交到对应路由
  • 若需使用Django admin后台,需为Admin模型注册到admin站点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:17:24