[英]Django models.py OneToOneField — help creating a relationship between two models
I am having trouble testing a relationship between two models (CustomUser and Profile) located in different apps. 我在测试位于不同应用程序中的两个模型(CustomUser和Profile)之间的关系时遇到麻烦。 I'm hoping someone can identify where I am going wrong here: 我希望有人可以在这里确定我要去哪里:
Here is my profiles/models.py --- you can see my user field attempting to create a OneToOne with with my users/models.py: 这是我的profile / models.py ---您可以看到我的用户字段试图与我的users / models.py创建一个OneToOne:
from django.db import models
from core.models import TimeStampedModel
class Profile(TimeStampedModel):
user = models.OneToOneField('users.CustomUser', on_delete=models.CASCADE)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
bio = models.TextField(blank=True)
image = models.URLField(blank=True)
def __str__(self):
return self.user.username
Here is my users/models.py: 这是我的users / models.py:
class CustomUser(AbstractBaseUser, PermissionsMixin, TimeStampedModel):
username = models.CharField(db_index=True, max_length=255, unique=True)
email = models.EmailField(db_index=True, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_provider = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = CustomUserManager()
def __str__(self):
return self.email
@property
def token(self):
return self._generate_jwt_token()
def get_short_name(self):
return self.username
def _generate_jwt_token(self):
dt = datetime.now() + timedelta(days=60)
token = jwt.encode({
'id': self.pk,
'exp': int(dt.strftime('%s'))
}, settings.SECRET_KEY, algorithm='HS256')
return token.decode('utf-8')
So the idea is that when I create a new user, a profile is automatically created as well. 因此,想法是当我创建一个新用户时,也会自动创建一个配置文件。 To do this, I am using a post_save signal in my users app: 为此,我在用户应用程序中使用了post_save信号:
users/signals.py: 用户/signals.py:
from django.db.models.signals import post_save
from django.dispatch import receiver
from conduit.apps.profiles.models import Profile
from .models import User
@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created:
instance.profile = Profile.objects.create(user=instance)
And finally an update to my users/ init .py file: 最后是我的users / init .py文件的更新:
from django.apps import AppConfig
class UsersAppConfig(AppConfig):
name = 'django.users'
label = 'users'
verbose_name = 'Users'
def ready(self):
import users.signals
default_app_config = 'django.users.UsersAppConfig'
That last update is something I am relatively unfamiliar with. 最后更新是我相对不熟悉的东西。 I suspect this is where my problem is located. 我怀疑这是我的问题所在。
I am able to resister a new user via an api call with no problem, however, when I test to see if a Profile object exists for that new user, I am left with the following error: 我能够通过api调用抵抗新用户,这没有问题,但是,当我测试以查看该新用户是否存在Profile对象时,会遇到以下错误:
python manage.py shell
from users.models import CustomUser
u = CustomerUser.objects.last()
u
<CustomUser:testuser@gmail.com> --- everything works to this point
u.profile --- this is where it breaks down
I'm left with this error in shell: 我在shell中留下了这个错误:
users.models.CustomUser.profile.RelatedObjectDoesNotExist: CustomUser has no profile.
Any help would be appreciated, thanks! 任何帮助,将不胜感激,谢谢!
I think your error is in your signal method: 我认为您的错误出在您的信号方法中:
from django.db.models.signals import post_save
from django.dispatch import receiver
from conduit.apps.profiles.models import Profile
from .models import User # you have CustomUser but you are calling User
@receiver(post_save, sender=User)
def create_related_profile(sender, instance, created, *args, **kwargs):
if instance and created: # you should only have created because you want this happen only when it is created
instance.profile = Profile.objects.create(user=instance)
Also, I see no need updating the users init.py
. 另外,我认为不需要更新用户init.py
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.