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

如何基于Django Rest Framework构建拆分式多用户模型?

Django Rest Framework 拆分用户模型实现方案

一、模型层实现(修正并补全)

你的核心思路可行,但需要补全模型继承关系和一对一关联字段,同时配置Django自定义用户模型:

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

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)
        # 自动创建关联的资料模型
        UserProfile.objects.create(user=user)
        UserProfileData.objects.create(user=user)
        return user

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

class User(AbstractBaseUser, PermissionsMixin):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    email = models.EmailField(unique=True, blank=False, max_length=255)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

class UserProfile(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    first_name = models.CharField(max_length=255, blank=False)
    last_name = models.CharField(max_length=255, blank=False)
    avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)
    birthday = models.DateField(blank=True, null=True)

class UserProfileData(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile_data')
    bio = models.CharField(max_length=400, blank=True)
    phone_number = models.CharField(max_length=20, blank=True)

注意:需在settings.py中配置AUTH_USER_MODEL = '你的应用名.User',替换为实际应用名称。

二、序列化器实现

根据不同业务场景创建序列化器,支持单独更新或组合返回完整用户信息:

1. 核心用户序列化器(注册/登录用)

from rest_framework import serializers
from .models import User, UserProfile, UserProfileData

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'email', 'password']
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

2. 用户资料序列化器(更新/查看用)

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ['first_name', 'last_name', 'avatar', 'birthday']

class UserProfileDataSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfileData
        fields = ['bio', 'phone_number']

3. 完整用户信息序列化器(返回前端完整数据)

class FullUserSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer()
    profile_data = UserProfileDataSerializer()

    class Meta:
        model = User
        fields = ['id', 'email', 'date_joined', 'profile', 'profile_data']

三、视图层实现

1. 用户注册视图

from rest_framework import generics
from rest_framework.permissions import AllowAny
from .serializers import UserSerializer

class UserRegistrationView(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]

2. 用户资料更新/查看视图

from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from .models import UserProfile, UserProfileData
from .serializers import UserProfileSerializer, UserProfileDataSerializer

class UserProfileView(generics.RetrieveUpdateAPIView):
    serializer_class = UserProfileSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return self.request.user.profile

class UserProfileDataView(generics.RetrieveUpdateAPIView):
    serializer_class = UserProfileDataSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return self.request.user.profile_data

3. 完整用户信息视图

class FullUserView(generics.RetrieveAPIView):
    serializer_class = FullUserSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        return self.request.user

四、关键注意事项

  • 自动创建关联模型:除了在UserManager中自动生成关联模型,也可通过Django信号实现,避免手动创建遗漏:
    from django.db.models.signals import post_save
    from django.dispatch import receiver
    
    @receiver(post_save, sender=User)
    def create_user_profiles(sender, instance, created, **kwargs):
        if created:
            UserProfile.objects.create(user=instance)
            UserProfileData.objects.create(user=instance)
    
  • 权限控制:所有涉及用户资料的视图必须添加IsAuthenticated权限,确保仅登录用户能访问自身数据。
  • 文件上传配置:使用ImageField需在settings.py中配置MEDIA_ROOT和MEDIA_URL,开发环境还需在urls.py中添加媒体文件路由。
  • 嵌套序列化器更新:若需通过单个接口同时更新用户及资料信息,需重写序列化器的update方法,手动处理嵌套字段的更新逻辑。
  • 登录验证:已将USERNAME_FIELD设为email,DRF的TokenAuthentication或JWT认证可直接使用邮箱+密码完成登录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:13:14