Пользовательская модель пользователя в rest-auth: RelatedObjectDoesNotExist

Я пытаюсь реализовать регистрацию с помощью библиотеки django rest-auth. Я выполнил все инструкции из руководства по установке и использованию, включая часть с настраиваемый пользовательский сериализатор. И тут начинаются проблемы. Мы регистрируем нового пользователя, подтверждаем электронную почту, и когда я пытаюсь обновить пользователя, я получаю ту же ошибку:

«RelatedObjectDoesNotExist в / rest-auth / user / У пользователя нет профиля пользователя».

Не могу понять, как оформить регистрацию, чтобы одновременно создать для него пользователя и профиль. Я знаю, что этот вопрос задавался раньше, но я не нашел ничего, что могло бы объяснить, почему это происходит. Я ищу простой РАБОЧИЙ пример регистрации с использованием django-rest-auth и пользовательской модели пользователя.

models.py:

class UserProfile(models.Model): 
     user = models.OneToOneField(User, primary_key=True, related_name='profile')
     tagline = models.CharField(max_length=140, null=True)
     created_at = models.DateTimeField(auto_now_add=True)
     updated_at = models.DateTimeField(auto_now=True)

     @receiver(post_save, sender=User)
     def create_profile_for_user(sender, instance=None, created=False, **kwargs):
        if created:
            UserProfile.objects.get_or_create(user=instance)

     @receiver(pre_delete, sender=User)
     def delete_profile_for_user(sender, instance=None, **kwargs):
        if instance:
           user_profile = UserProfile.objects.get(user=instance)
           user_profile.delete()

serilizers.py

class UserSerializer(UserDetailsSerializer):
    curriculumVitaeLink = serializers.CharField(source="userprofile.curriculumVitaeLink", required=False)
    class Meta(UserDetailsSerializer.Meta):
        fields = UserDetailsSerializer.Meta.fields + (
            'curriculumVitaeLink'
        )

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('userprofile', {})
        curriculumVitaeLink = profile_data.get('curriculumVitaeLink')
        instance = super(UserSerializer, self).update(instance, validated_data)

        # get and update user profile
        profile = instance.userprofile
        if profile_data :
            profile.curriculumVitaeLink = curriculumVitaeLink
            profile.save()
        return instance

    def destroy(self, request, pk=None, **kwargs):
        request.user.is_active = False
        request.user.save()
        return Response(status=204)

person Vasile    schedule 15.02.2018    source источник


Ответы (2)


RelatedObjectDoesNotExist ошибка здесь означает, что соответствующий объект UserProfile не был создан сигналом при создании объекта User. Основываясь на фрагменте вопроса, это может быть связано с тем, как были определены сигналы:

Сигналы Django необходимо определять на уровне модуля, а не как методы экземпляра модели - вам нужно сместить отступ влево:

 class UserProfile(models.Model): 
     user = models.OneToOneField(User, primary_key=True, 
     related_name='profile')
     tagline = models.CharField(max_length=140, null=True)
     created_at = models.DateTimeField(auto_now_add=True)
     updated_at = models.DateTimeField(auto_now=True)


 @receiver(post_save, sender=User)
 def create_profile_for_user(sender, instance=None, created=False, **kwargs):
    if created:
        UserProfile.objects.get_or_create(user=instance)

Таким образом, при регистрации должны быть созданы объекты User и UserProfile.

person Maxim Kukhtenkov    schedule 15.02.2018

Вы должны получить объект userprofile, используя related_name, который вы использовали в OneToOneField Следовательно:

profile = instance.userprofile

должно быть:

profile = instance.profile
person Peter Sobhi    schedule 15.02.2018
comment
Я думаю, что в какой-то момент это было изменено в авторском коде, потому что, если бы это было неправильное имя свойства, ошибка выглядела бы как AttributeError: 'User' object has no attribute 'userprofile'. Если ошибка RelatedObjectDoesNotExist, это означает, что имя свойства правильное, просто объекта не существует. - person Maxim Kukhtenkov; 15.02.2018
comment
Да ты прав. Эта ошибка возникает из-за того, что экземпляр профиля не был создан. как упомянул @MaximKukhtenkov - person Peter Sobhi; 15.02.2018