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

基于Django REST Framework自定义用户模型的密码创建求助

解决员工注册添加密码的两种方案

方案一:关联Django内置User模型(推荐)

Django自带的User模型已经封装了密码加密、登录认证等成熟功能,适合快速实现注册登录逻辑,步骤如下:

1. 修改Employee模型,关联User

给Employee添加一对一关联到User,复用User的密码、用户名字段:

from django.db import models
from django.contrib.auth.models import User

class Employee(models.Model):
    # 关联内置User模型,删除员工时同时删除关联的User
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employee')
    name = models.CharField(max_length=50, unique=True, verbose_name='Name')
    email = models.EmailField(verbose_name='Email')
    department = models.CharField(max_length=30, verbose_name='Departamento')
    # 其他自定义字段...

    def __str__(self):
        return self.name

2. 编写注册专用序列化器

创建包含User和Employee字段的序列化器,处理密码加密和双模型创建:

from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Employee

class EmployeeRegistrationSerializer(serializers.Serializer):
    # User模型字段(登录用)
    username = serializers.CharField(max_length=150)
    password = serializers.CharField(write_only=True)  # 只写字段,不返回给前端
    # Employee自定义字段
    name = serializers.CharField(max_length=50)
    email = serializers.EmailField()
    department = serializers.CharField(max_length=30)
    # 其他Employee字段...

    def create(self, validated_data):
        # 用create_user自动加密密码,创建User实例
        user = User.objects.create_user(
            username=validated_data['username'],
            password=validated_data['password']
        )
        # 创建关联的Employee实例
        employee = Employee.objects.create(
            user=user,
            name=validated_data['name'],
            email=validated_data['email'],
            department=validated_data['department']
            # 赋值其他自定义字段
        )
        return employee

3. 编写注册视图

用DRF的CreateAPIView快速实现注册接口:

from rest_framework.generics import CreateAPIView
from .serializers import EmployeeRegistrationSerializer

class EmployeeRegistrationView(CreateAPIView):
    serializer_class = EmployeeRegistrationSerializer

4. 配置路由

在urls.py中添加注册接口路由:

from django.urls import path
from .views import EmployeeRegistrationView

urlpatterns = [
    path('register/', EmployeeRegistrationView.as_view(), name='employee-register'),
    # 其他路由...
]

登录适配

注册完成后,直接用DRF内置的obtain_auth_token接口实现登录拿token:

# urls.py中添加
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns += [
    path('login/', obtain_auth_token, name='employee-login'),
]

方案二:给Employee直接添加密码字段

如果不想依赖内置User模型,可以直接给Employee加密码字段,手动处理加密逻辑:

1. 修改Employee模型

添加密码字段,并在保存时自动加密:

from django.db import models
from django.contrib.auth.hashers import make_password

class Employee(models.Model):
    name = models.CharField(max_length=50, unique=True, verbose_name='Name')
    email = models.EmailField(verbose_name='Email')
    department = models.CharField(max_length=30, verbose_name='Departamento')
    password = models.CharField(max_length=128)  # 存储哈希后的密码,长度设为128足够
    # 其他自定义字段...

    def save(self, *args, **kwargs):
        # 仅当密码未加密时进行加密(避免更新时重复加密)
        if self.password and not self.password.startswith('pbkdf2_sha256$'):
            self.password = make_password(self.password)
        super().save(*args, **kwargs)

    def __str__(self):
        return self.name

2. 编写注册序列化器

设置密码为只写字段,避免返回给前端:

from rest_framework import serializers
from .models import Employee

class EmployeeRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = Employee
        fields = ['name', 'email', 'department', 'password']  # 包含其他自定义字段

    def create(self, validated_data):
        # 模型save方法已处理加密,直接创建实例
        return Employee.objects.create(**validated_data)

3. 自定义认证后端(用于登录)

因为没有用内置User,需要自定义认证逻辑:

# 在app下创建backends.py
from django.contrib.auth.backends import BaseBackend
from .models import Employee
from django.contrib.auth.hashers import check_password

class EmployeeAuthBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            # 这里假设用name作为登录用户名,可根据需求改成email
            employee = Employee.objects.get(name=username)
            # 验证密码哈希
            if check_password(password, employee.password):
                return employee
        except Employee.DoesNotExist:
            return None

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

4. 配置认证后端

在settings.py中添加自定义后端:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'your_app_name.backends.EmployeeAuthBackend',  # 替换为你的app路径
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:45:42