Django: Как вложить два сериализатора друг в друга? - PullRequest
0 голосов
/ 13 июля 2020

Я хочу вложить сериализатор профиля в сериализатор моей истории для доступа к имени пользователя, изображению пользователя и т. Д. c. внутри рассказа. Сериализатор профиля содержит сериализатор сведений о пользователе для доступа к имени пользователя, идентификатору пользователя и т. Д. c. Таким образом, вся вложение выглядит так: Сериализатор пользователя -> сериализатор профиля -> сериализатор истории. Но когда я делаю это и получаю историю, я получаю сообщение об ошибке:

Got AttributeError when attempting to get a value for field `user` on serializer `ProfileSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `User` instance.
Original exception text was: 'User' object has no attribute 'user'.

Я искал возможные решения, но они не подходят для моей ситуации.

Модель пользователя :

class User(AbstractUser):

    pass

Сериализатор сведений о пользователе:

class UserDetailSerializer(serializers.ModelSerializer):
  class Meta:
    
    model = User
    fields = ('username','id', )

Модель профиля:

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics/')
  
    def __str__(self):
        return f'{self.user.username} Profile'

Сериализатор профиля:

class ProfileSerializer(serializers.ModelSerializer):
  user = UserDetailSerializer ()
  class Meta:
     model = Profile
     fields = ('id', 'user', 'image', 'bio')

Модель истории:

class Story (models.Model):
    title = models.CharField(max_length=100,blank=False)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)

    def __str__(self):
        return self.title

Сериализатор истории:

class StoryRetrieveSerializer (serializers.ModelSerializer):
    author = ProfileSerializer ()

    class Meta:
        model = Story 
        fields =  ('id','title', 'author')

Через API истории я хочу получить примерно следующее:

id: 1
title: "Test Title"
author: {username: "Test Author" , user id:1 , user image: "path"} // here the nested profile serialzer should provide the data

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Поскольку Story.auther является экземпляром Auth User, вы должны использовать сериализатор UserDetail вместо ProfileSerializer

class StoryRetrieveSerializer (serializers.ModelSerializer):
    <b>author = UserDetailSerializer()</b>

    class Meta:
        model = Story 
        fields =  ('id','title', 'author')

Update -1

class ProfileFooSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ('id', 'image', 'bio')


class UserFooDetailSerializer(serializers.ModelSerializer):
    profile = ProfileFooSerializer()

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


class StoryRetrieveSerializer(serializers.ModelSerializer):
    author = UserFooDetailSerializer()

    class Meta:
        model = Story
        fields = ('id', 'title', 'author')

Здесь я создал новые сериализаторы, чтобы сделать код чище.

0 голосов
/ 13 июля 2020

Например, рассмотрим модели ниже,

class Album(models.Model):
    album_name = models.CharField(max_length=100)
    artist = models.CharField(max_length=100)

class Track(models.Model):
    album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
    order = models.IntegerField()

Следующие ниже треки сериализованы в альбом,

class AlbumSerializer(serializers.ModelSerializer):
    tracks = serializers.StringRelatedField(many=True)

    class Meta:
        model = Album
        fields = ['album_name', 'artist', 'tracks']
...