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

时间:2018-11-27 01:04:27

标签: python django django-models

我无法测试位于不同应用程序中的两个模型(CustomUser和Profile)之间的关系。我希望有人可以在这里找到我要去的地方:

这是我的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

这是我的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')

因此,想法是当我创建一个新用户时,也会自动创建一个配置文件。为此,我在用户应用中使用了post_save信号:

users / 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)

最后是对我的用户的更新/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'

最后一次更新是我相对不熟悉的东西。我怀疑这是我的问题所在。

我能够通过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

我在shell中遇到这个错误:

users.models.CustomUser.profile.RelatedObjectDoesNotExist: CustomUser has no profile.

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您的错误出在您的信号方法中:

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)

此外,我认为不需要更新用户init.py