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

Django自定义注册用户时Profile未自动创建问题求助

问题排查:自定义User注册时Profile未自动生成及信号导入问题

问题描述

使用自定义注册表单创建User时,期望自动生成对应的Profile,但目前仅管理员后台手动创建Profile有效,自定义注册场景下Profile不会自动生成。访问/auth/profile/路径时触发错误:

RelatedObjectDoesNotExist at /auth/profile/ User has no profile. (user is creating but profile is not)

同时,apps.py中的import authenticate_me.signals语句显示灰色,IDE提示“未被使用”。

提供的代码

Models.py

from distutils.command.upload import upload
from email.policy import default
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import User
from PIL import Image
# Create your models here.

class User(AbstractUser):
    is_user = models.BooleanField(default=False)
    is_doctor = models.BooleanField( default=False)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

class User_reg(models.Model):
    user = models.OneToOneField('User',on_delete=models.CASCADE, primary_key=True)
    fname = models.CharField(max_length=50,blank=False)
    lname = models.CharField(max_length=50,blank=False)
    email = models.EmailField(max_length=100,blank=False)
    address = models.TextField(max_length=500,blank=False)
    gender = models.CharField(max_length=7, blank=False)
    phone = models.CharField(max_length=12,unique=True,blank=False)
    Username = models.CharField(max_length=100,blank=False,unique=True)
    Userpassword = models.CharField(max_length=100,blank=False)
    

    def __str__(self):
        return self.fname

class dr_reg(models.Model):
    user = models.OneToOneField('User',on_delete=models.CASCADE, primary_key=True)
    fname = models.CharField(max_length=50,blank=False)
    lname = models.CharField(max_length=50,blank=False)
    image = models.ImageField(upload_to="image")
    specialisation = models.CharField(max_length=100,blank=False)
    qualificaton =  models.CharField(max_length=100,blank=False)
    phone = models.CharField(max_length=12,blank=False,unique=True)
    gender = models.CharField(max_length=7,blank=False)
    address = models.TextField(max_length=500,blank=False)
    state =  models.CharField(max_length=50,blank=False)
    city = models.CharField(max_length=50,blank=False)
    zip = models.CharField(max_length=50,blank=False)
    email = models.EmailField(max_length=50,blank=False)
    dUsername = models.CharField(max_length=100,blank=False,unique=True)
    dPassword = models.CharField(max_length=100,blank=False)

    def __str__(self):
        return self.fname

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    avatar = models.ImageField(default='#', upload_to='profile_images')
    bio = models.TextField()

    def __str__(self):
        return self.bio

    def save(self, *args, **kwargs):
        super().save()

        img = Image.open(self.avatar.path)

        if img.height > 100 or img.width > 100:
            new_img = (100, 100)
            img.thumbnail(new_img)
            img.save(self.avatar.path)

views.py

def dr_register(request):
    if request.method == "POST":
        fname = request.POST.get('dfname')
        lname = request.POST.get('dlname')
        image = request.POST.get('img')
        qualification = request.POST.get('qualification')
        specialist = request.POST.get('specialisation')
        phone = request.POST.get('dphone')
        gender = request.POST.get('dsex')
        address = request.POST.get('dadd')
        state = request.POST.get('state')
        city = request.POST.get('city')
        zip = request.POST.get('zip')
        email = request.POST.get('demail')
        dr_username = request.POST.get('duname')
        dr_password = request.POST.get('dpass')

        mydoctor = User.objects.create_user(dr_username, email, dr_password)
        mydoctor.first_name = fname
        mydoctor.last_name = lname
        mydoctor.is_doctor = True
        mydoctor.save()

        dr_reg.objects.create(fname=fname,lname=lname,image=image, qualificaton=qualification, specialisation = specialist, phone= phone, gender=gender, address=address, state=state, city=city, zip=zip, email=email, dUsername=dr_username, dPassword= dr_password,user=mydoctor)
        # dr_register.save()  
    
        messages.success(request, 'Registeration successful')
        return render(request, 'user/login.html')  

    else:
        return render(request, 'doctor/register.html')

@login_required
def profile(request):
    if request.method == 'POST':
        user_form = UpdateUserForm(request.POST, instance=request.user)
        profile_form = UpdateProfileForm(request.POST, request.FILES, instance=request.user.profile)

        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, 'Your profile is updated successfully')
            return redirect(to='users-profile')
    else:
        user_form = UpdateUserForm(instance=request.user)
        profile_form = UpdateProfileForm(instance=request.user.profile)

        context = {
            'user_form': user_form,
            'profile_form': profile_form
        }

        return render(request, 'user/edit-profile.html', context)

signals.py

from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver

from .models import Profile


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance).save()

@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    instance.profile.save()

apps.py

from django.apps import AppConfig

class LoginModuleConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'authenticate_me'

    def ready(self):
        import authenticate_me.signals  

问题原因及修复步骤

1. 信号监听了错误的User模型

问题:signals.py中导入的是Django默认的django.contrib.auth.models.User,但项目使用的是自定义的User(AbstractUser),导致信号仅监听默认User的创建事件,自定义User创建时不会触发Profile生成逻辑。

修复:修改signals.py中的User导入,替换为项目自定义的User模型:

from django.db.models.signals import post_save
# 替换默认User导入为自定义User
from .models import User
from django.dispatch import receiver

from .models import Profile


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        # create()方法已自动保存,无需额外调用save()
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    instance.profile.save()

2. 未配置Django使用自定义User模型

问题:若settings.py中未设置AUTH_USER_MODEL,Django会继续使用默认User模型,信号和自定义User的关联逻辑会失效。

修复:在项目的settings.py中添加以下配置:

AUTH_USER_MODEL = 'authenticate_me.User'

3. 解决apps.py中导入未被使用的提示

问题:IDE提示import authenticate_me.signals未被使用,是因为导入语句仅用于加载信号,没有直接调用。

修复:可以添加注释告诉IDE忽略提示:

from django.apps import AppConfig

class LoginModuleConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'authenticate_me'

    def ready(self):
        # noqa 告诉IDE忽略未使用的提示
        import authenticate_me.signals  # noqa

4. 补全已存在的无Profile的用户

问题:之前创建的User可能没有对应的Profile,需要批量补全。

修复:在Django Shell中执行以下命令:

from authenticate_me.models import User, Profile
# 为所有无Profile的用户创建默认Profile
for user in User.objects.filter(profile__isnull=True):
    Profile.objects.create(user=user, bio='', avatar='#')

验证修复效果

  1. 重启Django服务器
  2. 通过自定义注册表单创建新User
  3. 访问/auth/profile/路径,确认不再出现RelatedObjectDoesNotExist错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:18:50