简体   繁体   English

Django models.py OneToOneField-帮助在两个模型之间创建关系

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM