使用自定义User模型扩展Django内置User模型,注册时如何关联二者?
Hey there! Let's fix this together. You've already set up a custom User model with a OneToOneField linking to Django's built-in User—great start! The issue right now is that when you register a new user via your signup view, only the Django User gets created, but your custom User instance isn't being generated automatically. That's exactly what Django signals are designed to handle.
What Are Signals, Anyway?
Signals are Django's way of letting you trigger actions in response to specific events (like when a model is saved or deleted). In your case, we'll use the post_save signal: this fires after a Django User is saved to the database, and we'll use it to create a matching custom User instance automatically.
Step 1: Fix Your Signal Code
You already have a post_save receiver in your code, but let's make sure it's set up correctly to create the custom User when a new Django User is created. Here's the updated code for your custom User model file:
from django.db import models from django.contrib.auth.models import User as UserDJANGO from django.db.models.signals import post_save from django.dispatch import receiver class User(models.Model): # Add related_name to avoid naming confusion later user_django = models.OneToOneField(UserDJANGO, on_delete=models.CASCADE, related_name="custom_user") user_animals = models.ManyToManyField(Animal, blank=True) def __str__(self): return self.user_django.email # Trigger this after a new Django User is created @receiver(post_save, sender=UserDJANGO) def create_custom_user(sender, instance, created, **kwargs): # Only create the custom User if this is a brand-new Django User (not an update) if created: User.objects.create(user_django=instance) # Optional: Keep the custom User in sync if the Django User is updated @receiver(post_save, sender=UserDJANGO) def save_custom_user(sender, instance, **kwargs): instance.custom_user.save()
Important: Ensure Signals Are Loaded
Django needs to detect your signals when the app starts. To guarantee this, update your app's apps.py file:
from django.apps import AppConfig class YourAppNameConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'your_app_name' def ready(self): # Import your models to load the signals import your_app_name.models
Then add this line to your app's __init__.py file to register the config:
default_app_config = 'your_app_name.apps.YourAppNameConfig'
Step 2: Verify Your Signup View
Your current signup view works perfectly for creating the Django User—now that the signal is in place, the custom User will be created automatically right after. No changes are needed here, but if you ever need to access the custom user for a logged-in user later, you can do it like this:
# In a view custom_user = request.user.custom_user # Uses the related_name we set earlier
Step 3: Test It Out
Now when you register a new user via your signup form:
- The
UserCreationFormsaves a new DjangoUser - The
post_savesignal detects this new user and creates a matching customUserinstance linked via theOneToOneField - You can check your database (via Django admin or shell) to confirm both records exist and are linked correctly.
Bonus: Avoid Naming Confusion
Since you're using User as your custom model name, it's easy to mix it up with Django's built-in User. A common practice is to rename your custom model to something like Profile—this makes your code more readable and avoids conflicts. For example:
class Profile(models.Model): user = models.OneToOneField(UserDJANGO, on_delete=models.CASCADE, related_name="profile") animals = models.ManyToManyField(Animal, blank=True) def __str__(self): return self.user.email
Then adjust your signals to use Profile instead of User—this will make your code much clearer in the long run.
内容的提问来源于stack exchange,提问作者Miguel Rodrigues

