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

Django超级用户编辑报错:RelatedObjectDoesNotExist(User has no profile)

问题描述

我能正常编辑非管理员权限的普通用户,但尝试编辑超级用户时触发报错:RelatedObjectDoesNotExist at /account/edit/ User has no profile。该超级用户是在添加Profile模型类及其属性并执行迁移操作后创建的,已花费数小时排查仍未解决,恳请帮助。


Models.py

from django.db import models
from django.contrib.auth.models import User

from django.conf import settings
class Profile(models.Model):
    print(f'------->{settings.AUTH_USER_MODEL}')
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    date_of_birth = models.DateField(blank=True, null=True, default=None)
    photo = models.ImageField(blank=True, upload_to="users/%Y/%m/%d/")
    def __str__(self):
        return f'Profile of {self.user.username}'

Views.py

from account.models import Profile

@login_required
def Edit(request):
    if request.method == "POST":
        user_form = UserEditForm(instance= request.user, data=request.POST)
        profile_form = ProfileEditForm(instance= request.user.profile,data=request.POST, files=request.FILES)
        if user_form.is_valid():
            user_form.save()
            profile_form.save()
            return render(request,'account/dashboard.html')
    else:
        user_form = UserEditForm(instance= request.user)
        profile_form = ProfileEditForm(instance= request.user.profile)
    return render(request, "account/edit.html",{'user_form':user_form})

forms.py

class UserEditForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name','email']
    def clean_email(self):
        data = self.cleaned_data['email']
        qs = User.objects.exclude(id=self.instance.id).filter(email=data)
        if qs.exists():
            raise forms.ValidationError('email already in use')
        else:
            return data
class ProfileEditForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['date_of_birth','photo']

edit.html

{% extends "base.html" %}
{% block content %}
    <html>
        <p>Please enter correct information bellow to edit</p>
        <form method="POST" enctype="multipart/form-data">
            {{user_form.as_p}}
            {{profile_form.as_p}}
            {% csrf_token %}
            <input type="submit" value="save changes" />
        </form>
    </html>
{% endblock %}

admin.py

from django.contrib import admin
from .models import Profile
# Register your models here.
@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
    list_display = ['user','date_of_birth', 'photo']
    raw_id_fields = ['user']

解决方法

1. 为现有超级用户手动补全Profile

进入Django Shell执行以下命令:

python manage.py shell
from django.contrib.auth.models import User
from account.models import Profile

# 替换成你的超级用户名
superuser = User.objects.get(username='你的超级用户名')
Profile.objects.create(user=superuser)

2. 自动为新用户创建Profile

在account/models.py中添加信号监听,确保新创建的用户(包括超级用户)自动生成Profile:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

3. 修复视图中的容错逻辑

修改views.py,避免直接访问request.user.profile触发崩溃,同时补上模板所需的profile_form传递:

@login_required
def Edit(request):
    # 获取或创建当前用户的Profile实例
    profile, created = Profile.objects.get_or_create(user=request.user)
    
    if request.method == "POST":
        user_form = UserEditForm(instance=request.user, data=request.POST)
        profile_form = ProfileEditForm(instance=profile, data=request.POST, files=request.FILES)
        # 同时验证两个表单的合法性
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            return render(request,'account/dashboard.html')
    else:
        user_form = UserEditForm(instance=request.user)
        profile_form = ProfileEditForm(instance=profile)
    # 将profile_form传递给模板
    return render(request, "account/edit.html",{'user_form':user_form, 'profile_form':profile_form})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:00:27