Django 'User' 对象没有属性 'userprofile' 但实例仍然被创建
Django 'User' object has no attribute 'userprofile' but instance is still created
我正在使用 Django allauth 进行身份验证,并创建了一个 UserProfile 模型来存储用户可以在稍后阶段更新的其他详细信息。我正在尝试使用信号在首次创建用户时创建 UserProfile 实例,并且仅在 UserProfile 已存在时更新它。
我遇到的问题是创建了 UserProfile 实例,但在调用堆栈中显示了此错误。当我删除信号代码时,运行 服务器并以管理员身份登录,我可以看到它已经创建,但是取消注释信号代码会阻止我以管理员身份登录或尝试 login/signup作为应用程序中的新用户。
回溯:
Traceback (most recent call last):
File "/Users/QP/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/QP/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 622, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 236, in inner
return view(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/views/decorators/debug.py", line 90, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/auth/admin.py", line 99, in add_view
return self._add_view(request, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/auth/admin.py", line 126, in _add_view
return super().add_view(request, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1670, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1549, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1599, in _changeform_view
self.save_model(request, new_object, form, not add)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1108, in save_model
obj.save()
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/auth/base_user.py", line 66, in save
super().save(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/db/models/base.py", line 743, in save
self.save_base(using=using, force_insert=force_insert,
File "/Users/QP/env/lib/python3.8/site-packages/django/db/models/base.py", line 791, in save_base
post_save.send(
File "/Users/QP/env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 170, in send
return [
File "/Users/QP/env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 171, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/Users/QP/core/models.py", line 64, in save_user_profile
instance.userprofile().save()
Exception Type: AttributeError at /admin/auth/user/add/
Exception Value: 'User' object has no attribute 'userprofile'
我知道 User 对象没有 'userprofile' 属性,但我不确定如何克服这个问题。我看过类似的解决方案 , here and here 但我一定遗漏了一些东西。
models.py:
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from datetime import date, datetime
from django.utils import timezone
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile', unique=True, on_delete=models.CASCADE)
sex = models.CharField(max_length=1, default='M', blank=True, null=True)
date_of_birth = models.DateField(default=date.today, blank=True, null=True)
date_joined = models.DateField(editable=False, auto_now_add=True, blank=True, null=True)
# durationfield
max_streak = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
curr_streak = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
total_days_clean = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
streak_start_date = models.DateTimeField(editable=True, default=timezone.now, blank=True, null=True)
streak_end_date = models.DateTimeField(editable=True, default=timezone.now, blank=True, null=True)
last_streak_end_date = models.DateTimeField(editable=True, default=timezone.now, blank=True, null=True)
curr_rank = models.CharField(max_length=150, default='n00b', blank=True, null=True)
highest_rank = models.CharField(max_length=150, default='n00b', blank=True, null=True)
bio = models.TextField(default='text', blank=True, null=True)
display_name = models.CharField(max_length=30, default='John Smith', blank=True, null=True)
REQUIRED_FIELDS = ('user',)
email = models.EmailField(blank=True, null=True)
# USERNAME_FIELD = 'username'
# username = models.CharField(max_length = 25, unique=True)
def __str__(self):
return self.user.email
@property
def is_anonymous(self):
"""
Always return False. This is a way of comparing User objects to
anonymous users.
"""
return False
@property
def is_authenticated(self):
"""
Always return True. This is a way of comparing User objects to
anonymous users.
"""
return True
@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()
forms.py:
from allauth.account.forms import SignupForm
from django import forms
from .models import User, UserProfile
from django.forms.widgets import NumberInput
import datetime
class UpdateUserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
# fields to be added in this form
fields = ['display_name', 'date_of_birth', 'bio']
views.py:
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import HttpResponse
from .models import User, UserProfile
from .forms import UpdateUserProfileForm
def update_user_profile(request):
# form = UpdateUserProfileForm(request.POST or None)
form = UpdateUserProfileForm(request.POST, instance=request.user.userprofile)
if form.is_valid():
form.save()
return redirect('profile')
messages.success(request, ('Your profile was successfully updated!'))
else:
messages.error(request, ('Please correct the error below.'))
context = {
'form': form
}
return render(request, 'update_profile.html', context)
我该如何解决这个问题?感谢任何帮助,谢谢。
它发生了,因为你设置了 related_name='profile'
然后你用 instance.userprofile.save()
调用它。将其更改为:
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
它应该能顺利运行:)
我正在使用 Django allauth 进行身份验证,并创建了一个 UserProfile 模型来存储用户可以在稍后阶段更新的其他详细信息。我正在尝试使用信号在首次创建用户时创建 UserProfile 实例,并且仅在 UserProfile 已存在时更新它。
我遇到的问题是创建了 UserProfile 实例,但在调用堆栈中显示了此错误。当我删除信号代码时,运行 服务器并以管理员身份登录,我可以看到它已经创建,但是取消注释信号代码会阻止我以管理员身份登录或尝试 login/signup作为应用程序中的新用户。
回溯:
Traceback (most recent call last):
File "/Users/QP/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/QP/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 622, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 236, in inner
return view(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/views/decorators/debug.py", line 90, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/auth/admin.py", line 99, in add_view
return self._add_view(request, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/auth/admin.py", line 126, in _add_view
return super().add_view(request, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1670, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1549, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1599, in _changeform_view
self.save_model(request, new_object, form, not add)
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1108, in save_model
obj.save()
File "/Users/QP/env/lib/python3.8/site-packages/django/contrib/auth/base_user.py", line 66, in save
super().save(*args, **kwargs)
File "/Users/QP/env/lib/python3.8/site-packages/django/db/models/base.py", line 743, in save
self.save_base(using=using, force_insert=force_insert,
File "/Users/QP/env/lib/python3.8/site-packages/django/db/models/base.py", line 791, in save_base
post_save.send(
File "/Users/QP/env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 170, in send
return [
File "/Users/QP/env/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 171, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/Users/QP/core/models.py", line 64, in save_user_profile
instance.userprofile().save()
Exception Type: AttributeError at /admin/auth/user/add/
Exception Value: 'User' object has no attribute 'userprofile'
我知道 User 对象没有 'userprofile' 属性,但我不确定如何克服这个问题。我看过类似的解决方案
models.py:
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User
from datetime import date, datetime
from django.utils import timezone
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile', unique=True, on_delete=models.CASCADE)
sex = models.CharField(max_length=1, default='M', blank=True, null=True)
date_of_birth = models.DateField(default=date.today, blank=True, null=True)
date_joined = models.DateField(editable=False, auto_now_add=True, blank=True, null=True)
# durationfield
max_streak = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
curr_streak = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
total_days_clean = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
streak_start_date = models.DateTimeField(editable=True, default=timezone.now, blank=True, null=True)
streak_end_date = models.DateTimeField(editable=True, default=timezone.now, blank=True, null=True)
last_streak_end_date = models.DateTimeField(editable=True, default=timezone.now, blank=True, null=True)
curr_rank = models.CharField(max_length=150, default='n00b', blank=True, null=True)
highest_rank = models.CharField(max_length=150, default='n00b', blank=True, null=True)
bio = models.TextField(default='text', blank=True, null=True)
display_name = models.CharField(max_length=30, default='John Smith', blank=True, null=True)
REQUIRED_FIELDS = ('user',)
email = models.EmailField(blank=True, null=True)
# USERNAME_FIELD = 'username'
# username = models.CharField(max_length = 25, unique=True)
def __str__(self):
return self.user.email
@property
def is_anonymous(self):
"""
Always return False. This is a way of comparing User objects to
anonymous users.
"""
return False
@property
def is_authenticated(self):
"""
Always return True. This is a way of comparing User objects to
anonymous users.
"""
return True
@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()
forms.py:
from allauth.account.forms import SignupForm
from django import forms
from .models import User, UserProfile
from django.forms.widgets import NumberInput
import datetime
class UpdateUserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
# fields to be added in this form
fields = ['display_name', 'date_of_birth', 'bio']
views.py:
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import HttpResponse
from .models import User, UserProfile
from .forms import UpdateUserProfileForm
def update_user_profile(request):
# form = UpdateUserProfileForm(request.POST or None)
form = UpdateUserProfileForm(request.POST, instance=request.user.userprofile)
if form.is_valid():
form.save()
return redirect('profile')
messages.success(request, ('Your profile was successfully updated!'))
else:
messages.error(request, ('Please correct the error below.'))
context = {
'form': form
}
return render(request, 'update_profile.html', context)
我该如何解决这个问题?感谢任何帮助,谢谢。
它发生了,因为你设置了 related_name='profile'
然后你用 instance.userprofile.save()
调用它。将其更改为:
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
它应该能顺利运行:)