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
相关产品推荐
相关产品推荐

