如何基于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
相关产品推荐
相关产品推荐

