Django models.py OneToOneField --- помогает создать отношения между двумя моделями - PullRequest
0 голосов
/ 27 ноября 2018

У меня проблемы с тестированием отношений между двумя моделями (CustomUser и Profile), расположенными в разных приложениях.Я надеюсь, что кто-то может определить, где я ошибаюсь:

Вот мои профили / models.py --- вы можете увидеть, как мое пользовательское поле пытается создать OneToOne с моими пользователями / models.py:

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

Вот мои пользователи / 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 / signal.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 file:

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

Я остался с этой ошибкой в ​​оболочке:

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

Любая помощь будет оценена, спасибо!

1 Ответ

0 голосов
/ 27 ноября 2018

Я думаю, что ваша ошибка в методе вашего сигнала:

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.

...