Django Rest Framework - обратная связь OneToOne - PullRequest
1 голос
/ 13 февраля 2020

У меня есть пользовательская модель пользователя и модель профиля пользователя.

class User(AbstractUser):
    """Custom User authentication class to use email as username"""
    username = None
    email = models.EmailField(verbose_name='email', max_length=255, unique=True,
                              error_messages={
                                  'unique': _(
                                          "A user is already registered with this email address"),
                              }, )

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
        return self.email


class UserProfile(models.Model):
    user = models.OneToOneField(User, to_field='email', on_delete=models.CASCADE)
    emp_id = models.CharField(max_length=20, blank=False, default='0', null=False)
    department = models.CharField(max_length=50, blank=True, default='', null=True)

Я пытаюсь написать сериализатор, который объединяет обе эти модели, создает вложенный JSON.

например:

{
  "email":"user@gmail.com",
  "is_active":true,
  "profile":
    {
      "emp_id":2,
      "department":2
    }
}

Это то, что я пытался сделать


class UserProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ('id', 'user', 'emp_id', 'department')


class UserPairSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(read_only=True)

    class Meta:
        model = User
        fields = ('id', 'email', 'is_active', 'profile')

Но по какой-то причине в моем ответе нет ни поля profile, ни ошибок , Я пытался следовать этой документации: https://www.django-rest-framework.org/api-guide/relations/

В чем проблема и как мне ее решить?

1 Ответ

2 голосов
/ 13 февраля 2020

Согласно документации , неявно ссылающейся на этот , 'обратные' запросы выполняются с использованием имени модели в нижнем регистре (в данном случае user.userprofile).

Таким образом, у вас есть две опции:

Либо вы указываете пользовательский related_name в поле user на модели UserProfile.

class UserProfile(models.Model):
    user = models.OneToOneField(User, to_field='email', on_delete=models.CASCADE, related_name='profile')

Или вы указываете source аргумент на вашем вложенном сериализаторе (см. документация ):

class UserProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ('id', 'user', 'emp_id', 'department')


class UserPairSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(read_only=True, source='userprofile')

    class Meta:
        model = User
        fields = ('id', 'email', 'is_active', 'profile')
...