Как передать дополнительный контекст в сериализаторы Django Rest Framework - PullRequest
0 голосов
/ 27 мая 2020

Это мой первый проект, использующий Django rest framework, и я изо всех сил пытаюсь понять это правильно. Я знаю, что в основной структуре Django, если мне нужно добавить дополнительные контексты в представление на основе классов, я сделаю что-то вроде этого:

class PostDetail(DetailView):
    model = Post

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books by a certain author John
        context['john_books'] = Book.objects.filter(author=john)
        return context

тогда я смогу получить доступ к контексту 'john_books' в моем шаблоне. Теперь мне нужно сделать то же самое, передав дополнительные контексты в мои PostViewSets. В подробном представлении я хочу получить доступ к списку сообщений, созданных этим автором сообщения в моей конечной точке api (что-то вроде «Сообщения от того же автора»). Я читал о get_serializer_context, но до сих пор не могу понять, как это реализовать. Вот что у меня есть до сих пор:

class PostViewSets(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

     def get_serializer_context(self):
        context = super(PostViewSets, self).get_serializer_context()
        author = self.get_object.author
        author_posts = self.get_queryset().filter(author=author)
        context.update({'author_posts': author_posts})
        return context

Я получаю эту ошибку:

AttributeError в / posts / объект 'function' не имеет атрибута 'author'

Моя модель сообщения:

class Post(models.Model):
    title = models.CharField(max_length=100, unique=True)
    body = models.TextField()
    is_featured = models.BooleanField(default=True)
    viewcount = models.IntegerField(default=0)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)

и мой класс PostSerializer:

class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer()

    class Meta:
        model = Post
        fields = ['id', 'title', 'body', 'author', 'viewcount', 'is_featured', 'created']

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Вы должны использовать get_object как забаву c, а не как свойство:

class PostViewSets(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

     def get_serializer_context(self):
        context = super(PostViewSets, self).get_serializer_context()
        author = self.get_object().author
        author_posts = self.get_queryset().filter(author=author)
        context.update({'author_posts': author_posts})
        return context
1 голос
/ 31 мая 2020

1. Сообщение об ошибке

AttributeError в объекте / posts / 'function' не имеет атрибута 'author'

явно объясняет, в чем и где проблема:

author = self.get_object.author

Думаю, вы пытались сделать что-то вроде этого

author = self.get_object().author

2. DRF ViewSet

ответы с данными, сериализованными соответствующим сериализатором. Таким образом, вам не нужно изменять ViewSet, но обновите сериализатор с помощью чего-то вроде:

class PostListSerializer(serializers.ModelSerializer):
    ... some fields ...

    class Meta:
        model = Post
        fields = [ ... some fields ... ]


class PostDetailsSerializer(serializers.ModelSerializer):
    ... some fields ...

    author_posts = PostListSerializer(source="author.post_set", many=True, read_only=True)

    class Meta:
        model = Post
        fields = [ ... some fields ... , 'author_posts']

или с помощью SerializerMethodField

    class PostDetailsSerializer(serializers.ModelSerializer):
    ... some fields ...

    author_posts = serializers.SerializerMethodField()

    def get_author_posts(self, obj):
        return PostListSerializer(instance=obj.post_set.all(), many=True).data

    class Meta:
        model = Post
        fields = [ ... some fields ... , 'author_posts']

Я не пробовал этот точный код, но это основная идея.

...