重写Django User模型后功能异常及AUTH_USER_MODEL报错解决求助
Hey there, let's break down your problems one by one and fix them step by step:
1. POST请求创建用户时附加字段被忽略的问题
原因分析
Your current UserSerializer only handles the default Django User model, and doesn't process the associated UserProfile fields. Additionally, when creating a user via POST, there's no logic to automatically create and populate a corresponding UserProfile instance.
解决方案
You have two solid options here:
Option 1: Nested Serializer + Override create Method
Modify your serializer to include nested UserProfile fields, then extend the create method to create both the User and UserProfile in one go:
from rest_framework import serializers from django.contrib.auth.models import User from .models import UserProfile class UserProfileSerializer(serializers.ModelSerializer): class Meta: model = UserProfile fields = ['avatar', 'university', 'discipline'] class UserSerializer(serializers.HyperlinkedModelSerializer): profile = UserProfileSerializer(write_only=True) class Meta: model = User fields = ['url', 'username', 'email', 'password', 'profile'] extra_kwargs = {'password': {'write_only': True}} def create(self, validated_data): # Extract profile data from the request profile_data = validated_data.pop('profile') # Create the core User instance user = User.objects.create_user(**validated_data) # Create and link the UserProfile UserProfile.objects.create(user=user, **profile_data) return user
Your POST request body should follow this structure:
{ "username": "new_user", "email": "user@example.com", "password": "secure_pass123", "profile": { "university": "ABC University", "discipline": "Electrical Engineering", "avatar": "path/to/avatar.png" } }
Option 2: Use Django Signals to Auto-Create UserProfile
If you prefer not to modify the serializer structure, use signals to automatically generate an empty UserProfile whenever a new User is created. You can then update the profile via a separate endpoint or subsequent request:
# models.py from django.db.models.signals import post_save from django.contrib.auth.models import User from django.dispatch import receiver @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: UserProfile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.userprofile.save()
2. AUTH_USER_MODEL Configuration Error
原因分析
Your UserProfile is a separate model linked to the default User via a OneToOneField, but Django requires AUTH_USER_MODEL to point to a model that inherits from AbstractUser or AbstractBaseUser—it can't be a related model. That's why you're getting the "model not installed" error.
解决方案
Refactor UserProfile to be a full custom user model by inheriting from AbstractUser:
Step 1: Update models.py
from django.contrib.auth.models import AbstractUser from django.db import models from django.contrib.auth.admin import UserAdmin class UserProfile(AbstractUser): # Add your custom fields directly (no more OneToOneField) avatar = models.ImageField(upload_to='avatars/', blank=True, null=True) # Add upload path for avatars university = models.CharField(max_length=100, default="") discipline = models.CharField(max_length=100, default="") joined_at = models.DateTimeField(auto_now_add=True) # Use auto_now_add for creation timestamp # Configure admin to handle your custom user model class CustomUserAdmin(UserAdmin): list_display = ('username', 'email', 'university', 'discipline', 'joined_at') fieldsets = ( (None, {'fields': ('username', 'password')}), ('Personal Info', {'fields': ('first_name', 'last_name', 'email', 'avatar', 'university', 'discipline')}), ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}), ('Important Dates', {'fields': ('last_login', 'date_joined', 'joined_at')}), ) admin.site.register(UserProfile, CustomUserAdmin)
Step 2: Update settings.py
AUTH_USER_MODEL = 'user.UserProfile'
⚠️ Critical Note: If you already have existing database data, changing AUTH_USER_MODEL requires a fresh migration (Django doesn't support modifying the core user model on an existing database). For new projects, just run python manage.py makemigrations and python manage.py migrate. For existing projects, backup your data first, reset the database, then re-run migrations.
Step 3: Update the Serializer
Now use your custom user model directly in the serializer:
from rest_framework import serializers from .models import UserProfile class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = UserProfile fields = "__all__" extra_kwargs = {'password': {'write_only': True}} def create(self, validated_data): user = UserProfile.objects.create_user(**validated_data) return user
Quick Recap
- Use the OneToOne + signal/nested serializer approach if you just need to add extra fields to the default user model.
- Use the
AbstractUserinheritance approach if you want a fully customized user model (this is Django's recommended method for custom user models).
内容的提问来源于stack exchange,提问作者Mostafa Ghadimi

